You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a proposal, not a PR. CONTRIBUTING.md asks for the design choice and rejected alternatives up front, and this touches CI config and a service-layer model, so I would rather get a reaction before writing it. Happy to be told the scope is wrong or that it is not wanted.
The problem I think is actually blocking things
There are four PRs open or closed against the same platform gap — #48, #32, #51, and #29 (closed) — plus three issues (#1, #24, #31). None have landed. Reading them together, the pattern is not that any of them is wrong. It is that each one patches a different layer, because there is no agreed place where "which platform are we on" gets decided:
Meanwhile sys.platform and os.name appear nowhere in src/, and app.py imports LaunchdSchedulerAdapter unconditionally. So there is currently no seam to guard at, and any reviewer has to decide the architecture and the fix in the same pass.
The second half: nothing is verifiable
All three workflows (ci.yml, pack-check.yml, publish.yml) run ubuntu-latest only, while the product supports macOS only. That has two consequences that I do not think are obvious:
1. The macOS-only automation subsystem is never exercised on macOS.sync, garden and update scheduling is the product's background loop, and CI has never run it on its target platform.
2. The launchd tests currently pass on Ubuntu by taking error paths.launchd_target() calls os.getuid(), which exists on Linux, so the code proceeds to shell out to launchctl. That binary is absent, run_launchctl catches the OSError and converts it to returncode=1, and the assertions are satisfied by the failure. So green CI on those tests is not evidence that scheduling works — and I only noticed because on Windows os.getuid does not exist at all and the same tests fail loudly instead of quietly.
Combined with the note in #24 that none of the devs have a Windows machine, I think this is the real reason platform PRs stall: they are unreviewable. A maintainer is asked to merge code for an OS they cannot run, verified only by the contributor's word.
What I would like to build
Three steps, as separate small PRs, in this order. Each is useful alone and each is revertible.
1. Make the scheduler port platform-neutral. This is the part I think is load-bearing and is not in any of the existing PRs. plist_path is currently a field on the service-layerScheduledJob and ScheduledJobStatus (services/automation/models.py), and it is part of the public --json output. So the launchd integration has leaked upward into the service contract — which is what makes "just add another adapter" not actually possible, and is arguably against this repo's own "keep modules honest" rule. I would replace it with something adapter-agnostic (a generic adapter-owned handle field), keeping the current --json key as a macOS-only alias if you want no output break.
2. Adopt #51's seam rather than re-inventing it.@YasienDwieb already added core/platform.py and an unsupported.py adapter in #51, which is the layer the others work around. I would rather build on that PR than compete with it — if #51 is close to acceptable, merging it first makes steps 1 and 3 much smaller, and I am happy to review or extend it instead of writing my own. I do not want to duplicate anyone's work here, which is also why I have deliberately stayed out of the OpenCode harness area given #28/#42.
3. Add a CI matrix, with honest platform markers.ubuntu-latest + macos-latest + windows-latest on ci.yml, and @pytest.mark.skipif(sys.platform != "darwin") on the tests that genuinely only mean something on macOS (the launchd ones). The marker half matters as much as the matrix: without it, "green on Windows" is achieved by tests passing for the wrong reason, which is the situation on Ubuntu today.
The point of step 3 is specifically to solve the hardware problem. Once it exists, a Windows or Linux PR is verified by the repo's own CI rather than by a contributor's screenshot, and you can review platform changes without owning the platform.
Rejected alternatives
Fix each command's guard as it is reported (the current trajectory). Cheapest per fix, but it is four PRs and counting for one missing seam, and each new command re-opens the question.
Add Windows to CI first, before the seam. Tempting since it is the smallest diff, but it would just turn CI red with no path to green, which is worse than no signal.
No change to the local-only model, the run queue, or the wiki format. No new public env vars or CLI flags. Nothing about hosted features.
Where I am coming from
I am on Windows 11 and have been running the suite there — 13 failed, 550 passed on a clean checkout. I have opened #64, #65 and #66 for three root causes that are independent of this proposal (test-sandbox escape, a path containment guard that does not hold off POSIX, and a .MD glob crash that also affects macOS). Those stand on their own; this issue is about the structural gap underneath the platform ones.
Two questions, and I will not start until there is a signal either way:
Is the direction right, and is step 1 (getting plist_path out of the service model) something you would accept?
This is a proposal, not a PR.
CONTRIBUTING.mdasks for the design choice and rejected alternatives up front, and this touches CI config and a service-layer model, so I would rather get a reaction before writing it. Happy to be told the scope is wrong or that it is not wanted.The problem I think is actually blocking things
There are four PRs open or closed against the same platform gap — #48, #32, #51, and #29 (closed) — plus three issues (#1, #24, #31). None have landed. Reading them together, the pattern is not that any of them is wrong. It is that each one patches a different layer, because there is no agreed place where "which platform are we on" gets decided:
SetupService, before mutationAutomationService.reconcileandconfig setcore/platform.py+ anunsupportedscheduler adaptersystemdadapter next tolaunchdMeanwhile
sys.platformandos.nameappear nowhere insrc/, andapp.pyimportsLaunchdSchedulerAdapterunconditionally. So there is currently no seam to guard at, and any reviewer has to decide the architecture and the fix in the same pass.The second half: nothing is verifiable
All three workflows (
ci.yml,pack-check.yml,publish.yml) runubuntu-latestonly, while the product supports macOS only. That has two consequences that I do not think are obvious:1. The macOS-only automation subsystem is never exercised on macOS.
sync,gardenandupdatescheduling is the product's background loop, and CI has never run it on its target platform.2. The
launchdtests currently pass on Ubuntu by taking error paths.launchd_target()callsos.getuid(), which exists on Linux, so the code proceeds to shell out tolaunchctl. That binary is absent,run_launchctlcatches theOSErrorand converts it toreturncode=1, and the assertions are satisfied by the failure. So green CI on those tests is not evidence that scheduling works — and I only noticed because on Windowsos.getuiddoes not exist at all and the same tests fail loudly instead of quietly.Combined with the note in #24 that none of the devs have a Windows machine, I think this is the real reason platform PRs stall: they are unreviewable. A maintainer is asked to merge code for an OS they cannot run, verified only by the contributor's word.
What I would like to build
Three steps, as separate small PRs, in this order. Each is useful alone and each is revertible.
1. Make the scheduler port platform-neutral. This is the part I think is load-bearing and is not in any of the existing PRs.
plist_pathis currently a field on the service-layerScheduledJobandScheduledJobStatus(services/automation/models.py), and it is part of the public--jsonoutput. So the launchd integration has leaked upward into the service contract — which is what makes "just add another adapter" not actually possible, and is arguably against this repo's own "keep modules honest" rule. I would replace it with something adapter-agnostic (a generic adapter-owned handle field), keeping the current--jsonkey as a macOS-only alias if you want no output break.2. Adopt #51's seam rather than re-inventing it. @YasienDwieb already added
core/platform.pyand anunsupported.pyadapter in #51, which is the layer the others work around. I would rather build on that PR than compete with it — if #51 is close to acceptable, merging it first makes steps 1 and 3 much smaller, and I am happy to review or extend it instead of writing my own. I do not want to duplicate anyone's work here, which is also why I have deliberately stayed out of the OpenCode harness area given #28/#42.3. Add a CI matrix, with honest platform markers.
ubuntu-latest+macos-latest+windows-latestonci.yml, and@pytest.mark.skipif(sys.platform != "darwin")on the tests that genuinely only mean something on macOS (thelaunchdones). The marker half matters as much as the matrix: without it, "green on Windows" is achieved by tests passing for the wrong reason, which is the situation on Ubuntu today.The point of step 3 is specifically to solve the hardware problem. Once it exists, a Windows or Linux PR is verified by the repo's own CI rather than by a contributor's screenshot, and you can review platform changes without owning the platform.
Rejected alternatives
schtasksWindows scheduler now. Out of scope until the port is neutral; degrading cleanly is worth more than scheduling on Windows, and bug: setup --yes crashes on Linux because scheduled automation is macOS/launchd-only #31 shows the crash is the actual user-facing bug.What I am not proposing
No change to the local-only model, the run queue, or the wiki format. No new public env vars or CLI flags. Nothing about hosted features.
Where I am coming from
I am on Windows 11 and have been running the suite there —
13 failed, 550 passedon a clean checkout. I have opened #64, #65 and #66 for three root causes that are independent of this proposal (test-sandbox escape, a path containment guard that does not hold off POSIX, and a.MDglob crash that also affects macOS). Those stand on their own; this issue is about the structural gap underneath the platform ones.Two questions, and I will not start until there is a signal either way:
plist_pathout of the service model) something you would accept?