Stage
connect
Coding agent
OpenAI Codex
Coding agent version
Codex desktop; Monk plugin v0.1.54 (2a4f9cf)
Repro steps
The macOS launcher's healthy-agent reuse gate reads the generated launchd plist with regular-expression grep patterns even though it is comparing literal configuration values.
I reproduced the exact Darwin branch with a network-free fixture:
- Use an isolated
HOME, stub uname to Darwin, and return the expected protected-resource document from the health probe.
- Put a launchd plist at
~/Library/LaunchAgents/io.monk.agent.plist containing all current values except the previous auth URL is the distinct, valid URL https://auth-monk-io.
- Invoke
scripts/start-monk-agent.sh with the requested default MONK_AUTH_URL=https://auth.monk.io.
- Record whether the fixture
launchctl is invoked to restart the companion.
The current release fails the regression:
launchd fast path falsely accepted a different stored auth URL
The requested value is interpolated into this regex:
grep -q "<string>$auth_url</string>" "$launchd_plist"
Each . in https://auth.monk.io is therefore a wildcard, so it incorrectly matches the stored <string>https://auth-monk-io</string>.
Expected behavior
The launcher should compare launch configuration literally. When the requested auth issuer differs from the one in the launchd plist, it should restart the healthy companion once so the new process inherits the current value.
Actual behavior
Regex metacharacters in the requested auth URL can match different stored characters. launchd_configured returns true, the launcher exits through its healthy fast path, and the process keeps the previous authentication configuration even though startup reports success.
The same non-literal comparison is used for auth client ID, audience, autospin URL, local mode, and plugin version. URLs contain dots by default, making this more than a hypothetical regex-input surface.
I validated the minimal fix locally: use grep -Fq for every literal launchd value, matching the existing fixed-string check already used for agent_path. The focused regression then forces the expected launchd restart and passes; the Antigravity config regression, sh -n, and git diff --check also pass.
Collision check
Searches for launchd auth URL drift, launchd regex configuration, fixed-string plist matching, and launchd_configured found no matching report.
Severity (your guess)
major
The launcher reports success while the running companion can remain bound to an old OAuth issuer/client/audience or autospin endpoint. Authentication can then fail in a way that contradicts the visible environment. Removing the old agent/plist or causing an unrelated restart is a workaround.
OS
Windows 11 with an isolated shell fixture selecting the exact Darwin branch; no native-macOS claim.
monkd version
Not involved; the defect is in companion reuse before runtime operations.
Target cloud
None; network-free launcher fixture.
Integration
Monk plugin macOS launchd lifecycle
Fix PR
Draft PR #268 adds the current-release red-to-green regression and the validated fixed-string comparison across all three shipped launcher mirrors. It remains draft only because GitHub limits contributors without write access to four ready PRs at once.
Stage
connect
Coding agent
OpenAI Codex
Coding agent version
Codex desktop; Monk plugin v0.1.54 (
2a4f9cf)Repro steps
The macOS launcher's healthy-agent reuse gate reads the generated launchd plist with regular-expression
greppatterns even though it is comparing literal configuration values.I reproduced the exact Darwin branch with a network-free fixture:
HOME, stubunametoDarwin, and return the expected protected-resource document from the health probe.~/Library/LaunchAgents/io.monk.agent.plistcontaining all current values except the previous auth URL is the distinct, valid URLhttps://auth-monk-io.scripts/start-monk-agent.shwith the requested defaultMONK_AUTH_URL=https://auth.monk.io.launchctlis invoked to restart the companion.The current release fails the regression:
The requested value is interpolated into this regex:
Each
.inhttps://auth.monk.iois therefore a wildcard, so it incorrectly matches the stored<string>https://auth-monk-io</string>.Expected behavior
The launcher should compare launch configuration literally. When the requested auth issuer differs from the one in the launchd plist, it should restart the healthy companion once so the new process inherits the current value.
Actual behavior
Regex metacharacters in the requested auth URL can match different stored characters.
launchd_configuredreturns true, the launcher exits through its healthy fast path, and the process keeps the previous authentication configuration even though startup reports success.The same non-literal comparison is used for auth client ID, audience, autospin URL, local mode, and plugin version. URLs contain dots by default, making this more than a hypothetical regex-input surface.
I validated the minimal fix locally: use
grep -Fqfor every literal launchd value, matching the existing fixed-string check already used foragent_path. The focused regression then forces the expected launchd restart and passes; the Antigravity config regression,sh -n, andgit diff --checkalso pass.Collision check
Searches for launchd auth URL drift, launchd regex configuration, fixed-string plist matching, and
launchd_configuredfound no matching report.Severity (your guess)
major
The launcher reports success while the running companion can remain bound to an old OAuth issuer/client/audience or autospin endpoint. Authentication can then fail in a way that contradicts the visible environment. Removing the old agent/plist or causing an unrelated restart is a workaround.
OS
Windows 11 with an isolated shell fixture selecting the exact Darwin branch; no native-macOS claim.
monkd version
Not involved; the defect is in companion reuse before runtime operations.
Target cloud
None; network-free launcher fixture.
Integration
Monk plugin macOS launchd lifecycle
Fix PR
Draft PR #268 adds the current-release red-to-green regression and the validated fixed-string comparison across all three shipped launcher mirrors. It remains draft only because GitHub limits contributors without write access to four ready PRs at once.