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
The clean machine workflow (the install check) has failed on every run of main since it was
merged in #4 — 6a931b1, 1510f6d, 4f10635, 8fdab67, b6ee2ad. A check that is always red is not
a gate: PR #8 landed with it failing and nobody could tell from the check whether that PR caused it.
Its two MISSes are not CI artifacts. Both are real, and one of them is a user-visible defect on a
genuinely fresh install:
MISS failed user units: macarchy-auto-appearance.service macarchy-bar-contrast.service macos-dynamic-wallpaper.service
MISS dynamic wallpaper config: macos-dynamic-wallpaper: wallpaper not found:
/home/runner/.config/omarchy/backgrounds/apple-glass/26-tahoe-beach-day.jpg
The wallpaper MISS is a genuine bug the laptop cannot see.macos-dynamic-wallpaper seeds its
default config from examples/dynamic-wallpaper.json, which names the tahoe-beach set
(26-tahoe-beach-dawn/day/dusk/night.jpg). apple-glass/backgrounds/ ships three files:
1-sequoia-dusk.jpg 2-graphite.jpg 3-aurora.jpg
Nothing in REPOS installs a 26-tahoe-* file. It is green on the maintainer's laptop only because
those files already sit in ~/.config/omarchy/backgrounds/apple-glass/ from local history — exactly
the class of bug the comment at the top of clean-machine.yml says the workflow exists to catch.
The failed-units MISS cannot currently be diagnosed at all.tests/clean-machine.sh never dumps journalctl --user -u <unit> for a unit it reports as failed, so CI states the symptom and withholds
the cause. Whether those three units legitimately cannot run without a compositor, or are genuinely
broken on a clean machine, is not answerable from the run log.
Expected
clean machine is green on main, and goes red only when a change actually breaks a clean install —
so it can gate again.
Area
CI / doctor.sh / the component install chain.
Related:#4 (introduced the workflow), #8 (evidence gathered in its comment)
🧠 Brainstorm
Problem / context
clean-machine.yml was added in #4 with an explicit rationale: "Nothing ever ran install.sh anywhere
but the one laptop, and that is exactly how two 'nobody wired the startup' bugs survived." It worked —
it found a third such bug immediately. But the run was never brought back to green, so the signal was
lost the moment it was produced: five consecutive red runs later, the check carries no information,
and the one PR open against the repo had to be merged past it by hand.
The two MISSes are different in kind and must not be treated as one:
The wallpaper one is a product defect. A user who installs the suite today on a clean machine
gets a dynamic-wallpaper config pointing at four files nobody ships. It is not about CI at all; CI
is merely the only place it is visible.
The failed-units one is unknown. It may be a product defect too, or it may be three units that
legitimately cannot start without a compositor. The run log does not say, and guessing which is
precisely the failure mode ci: prove install.sh and doctor.sh on a clean machine #4 was written to end.
Approaches
A. Gate the failing checks off on CI (MACARCHY_NO_HARDWARE-style skip) and move on.
Green immediately, one line per check. But it would suppress the wallpaper MISS, which is a real bug
on real machines — it would turn the one workflow that found a genuine defect into one that is
configured not to. Rejected.
B. Fix the defects, leave the workflow alone.
Honest, but blocked out of the gate: the failed-units MISS cannot be fixed before it can be read, and
nothing in the run log says why those units failed.
C. Diagnose first, then fix, then let the check gate again.(recommended)
Make CI say why a unit failed (Task 1), which costs a handful of lines and permanently improves
every future red run. Then fix the wallpaper defect at its source (Task 2), and dispose of the three
units on the evidence Task 1 produces (Task 3) — either a real fix, or a narrow documented skip for
what genuinely needs a compositor, decided from a journal rather than from a guess.
Recommendation
C. The order is the point: Task 1 is what turns Task 3 from speculation into a decision, and it is
the cheapest of the three. Approach A is explicitly rejected — a skip is only acceptable for something
proven to need hardware CI does not have, which is what Task 1 establishes and Task 3 applies.
📋 Spec
Goal
clean machine green on main and meaningful as a gate, with both MISSes resolved on their merits —
no MISS silenced that a real machine would also report.
Scope
tests/clean-machine.sh — dump the journal of every failed user unit before doctor.sh decides.
The seeded dynamic-wallpaper default — make a clean install name wallpapers that are actually installed.
The three failing units — fix, or narrowly skip with a stated reason, per Task 1's evidence.
Non-goals
Any change to doctor.sh's verdicts on a real laptop. The doctor is reporting the truth; this issue
is about making the truth actionable and then making it green.
Restructuring the component install chain.
Design
flowchart TD
A[install.sh twice] --> B[dump journal of each failed user unit]
B --> C[doctor.sh decides]
C -->|wallpaper MISS| D[seeded default names a shipped set]
C -->|units MISS| E{journal says why}
E -->|needs a compositor| F[narrow skip, reason stated]
E -->|genuinely broken| G[fix the unit]
Loading
The wallpaper fix has two viable shapes, and Task 2 picks one on evidence rather than in advance:
either apple-glass ships the 26-tahoe-beach-* set it is already assumed to own, or the seeded default names a set apple-glass does ship (1-sequoia-dusk and friends). The second is
smaller and stays inside this repo's dependency direction; the first is right if those wallpapers were
always meant to be part of the theme. Whichever lands, the check that proves it is the same.
Edge cases
A unit that failed and was then restarted must not be reported — systemctl --user --failed already
reflects only the current state.
The journal dump must not fail the step when a unit has no journal (|| true), and must not run at
all when nothing failed.
macarchy-failed@<unit>.service instances fold onto their target in doctor.sh:63; the dump must
use the folded name, not the instance.
Assumptions
The three units fail for want of a compositor / Omarchy install rather than a packaging defect — unverified, and Task 1 exists precisely to settle it. Task 3 is written to accept either answer.
26-tahoe-beach-*.jpg on the maintainer's laptop came from local history, not from any repo in REPOS — established by find over apple-glass returning nothing.
Acceptance criteria
On a clean runner, a failed user unit's journal appears in the run log, under the unit's name.
clean machine is green on main — doctor.sh reports 0 missing.
A fresh install produces a dynamic-wallpaper config whose every referenced file exists on disk; macos-dynamic-wallpaper status exits 0 with no wallpaper not found.
Any check skipped on CI names the reason in its skip line, and still reports MISS on a real
laptop where the condition does not hold.
Re-running tests/clean-machine.sh twice in a row is still idempotent — the second run adds no new MISS.
Testing decisions
Seams under test:tests/clean-machine.sh's stdout and exit code (the whole workflow step is one
script, already the CI seam), and doctor.sh's MISS/ok lines — the same text-level seam tests/test_doctor_notify.sh and tests/test_doctor_touchbar_modules.sh already assert through. Prior art:tests/test_doctor_touchbar_modules.sh — temp HOME, PATH stubs, a stubbed journalctl replaying a fixture. A good test here: stub systemctl --user --failed to report one unit, assert the journal for that
unit reaches stdout and that a run with nothing failed emits no dump.
Out of scope
Making clean machine a required check — that is a branch-protection decision for the owner once it
is reliably green.
The 26-tahoe-* wallpapers' provenance or licensing.
🛠️ Implementation plan
For agentic workers: execute this plan task-by-task with implement-issue (subagent-per-task for broad plans, inline for small ones). Steps use checkbox (- [ ]) syntax for tracking.
Goal:clean machine green on main and gating again, with both MISSes resolved on their merits. Architecture: plain bash — install.sh, doctor.sh, tests/*.sh; the suites are hermetic (temp HOME + PATH stubs) and CI runs tests/test_*.sh plus bash -n. Tech stack: bash 5, gh, GitHub Actions on ubuntu-24.04-arm.
Seams under test:tests/clean-machine.sh's stdout and exit code, and doctor.sh's MISS/ok lines — the text-level seam the existing doctor suites already assert through.
Global constraints
Hermetic suites only: temp HOME, PATH stubs, no compositor, no Apple hardware. CI runs tests/test_*.sh by glob — a new suite must match it.
bash -n must pass on install.sh, boot.sh, doctor.sh and tests/*.sh.
Never silence a check that a real laptop would legitimately report. A skip states its reason and is gated on a condition that is false on the laptop.
Conventional Commit PR title decides the release bump; commits below use fix.
Commit trailer: Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>.
Task 1: CI says WHY a user unit failed
Files: modify tests/clean-machine.sh; test tests/test_clean_machine_journal.sh (new).
Interfaces: after the install.sh runs and before doctor.sh, for each unit in systemctl --user --failed --no-legend --plain, print a labelled journalctl --user -u <unit> --no-pager -n 40 block. Folds macarchy-failed@<u>.service onto <u> the same way doctor.sh:63 does.
Step 1: Write the failing test in tests/test_clean_machine_journal.sh (seam: the script's stdout) — stub systemctl to report one failed unit and journalctl to emit a marker line; assert the marker and the unit name both reach stdout.
Step 2: Add the second case to the same suite — systemctl --user --failed reports nothing, assert no dump block is emitted.
Step 3: Run bash tests/test_clean_machine_journal.sh → FAIL (no dump exists yet).
Step 4: Implement the dump block in tests/clean-machine.sh, || true on the journal call so a unit with no journal cannot fail the step.
Step 5: Re-run the suite → PASS, and bash -n clean on every tests/*.sh.
Step 6: Commit: fix(ci): dump the journal of every failed user unit on a clean machine.
Step 7: Push, let clean machine run, and record the three units' journals in a comment on this issue — Task 3 is written against that output.
Task 2: a fresh install names wallpapers it actually installs
Files: modify whichever of macos-dynamic-wallpaper's seeded default or apple-glass/backgrounds/ the evidence selects (cross-repo — see note); modify tests/clean-machine.sh only if a new assertion is needed.
Interfaces: after a clean install.sh, macos-dynamic-wallpaper status exits 0 and every path in the seeded config exists.
Step 1: Establish which repo owns the 26-tahoe-beach-* set — git log in apple-glass for a removal, and the provenance of the copies in ~/.config/omarchy/backgrounds/apple-glass/. Record the finding in a comment on this issue.
Step 2: Decide on that evidence: apple-glass ships the set, or the seeded default names a set apple-glass ships. State the choice and why in the same comment.
Step 3: Write the failing assertion — extend tests/clean-machine.sh so a wallpaper not found in doctor.sh's output fails the step with that line quoted (seam: the script's exit code + stdout).
Step 4: Run tests/clean-machine.sh locally against a temp HOME → FAIL on the missing wallpaper.
Step 5: Apply the chosen fix in the owning repo. If it lands outside macarchy-install, open the PR there and link it here — do not vendor another repo's assets into this one.
Step 6: Re-run → PASS.
Step 7: Commit: fix(install): seed a dynamic-wallpaper default whose files are installed.
Task 3: dispose of the three failing units on Task 1's evidence
Files: modify doctor.sh and/or the failing units' installers, per the journals; test tests/test_doctor_notify.sh (extend).
Interfaces:doctor.sh reports 0 missing on a clean runner without hiding anything a laptop would report.
Step 1: Read the journals Task 1 published on this issue and classify each of the three units: needs a compositor / Omarchy, or genuinely broken on a clean machine.
Step 2: For every unit in the first class — write the failing test first: assert doctor.sh prints skip with a stated reason when the gating condition is set, and MISS when it is not (seam: doctor.sh's output lines).
Step 3: Run → FAIL.
Step 4: Implement, following MACARCHY_NO_HARDWARE's existing shape — a named condition CI sets and the laptop never does.
Step 5: For every unit in the second class, fix the unit itself and note the defect in a comment; do not skip it.
Step 6: Re-run the full suite and bash -n → PASS.
Step 7: Commit: fix(doctor): resolve the user units that fail on a clean machine.
Step 8: Confirm clean machine is green on the PR, then say in the PR body that the check is ready to be made required.
Problem
The
clean machineworkflow (theinstallcheck) has failed on every run ofmainsince it wasmerged in #4 —
6a931b1,1510f6d,4f10635,8fdab67,b6ee2ad. A check that is always red is nota gate: PR #8 landed with it failing and nobody could tell from the check whether that PR caused it.
Its two
MISSes are not CI artifacts. Both are real, and one of them is a user-visible defect on agenuinely fresh install:
The wallpaper MISS is a genuine bug the laptop cannot see.
macos-dynamic-wallpaperseeds itsdefault config from
examples/dynamic-wallpaper.json, which names thetahoe-beachset(
26-tahoe-beach-dawn/day/dusk/night.jpg).apple-glass/backgrounds/ships three files:Nothing in
REPOSinstalls a26-tahoe-*file. It is green on the maintainer's laptop only becausethose files already sit in
~/.config/omarchy/backgrounds/apple-glass/from local history — exactlythe class of bug the comment at the top of
clean-machine.ymlsays the workflow exists to catch.The failed-units MISS cannot currently be diagnosed at all.
tests/clean-machine.shnever dumpsjournalctl --user -u <unit>for a unit it reports as failed, so CI states the symptom and withholdsthe cause. Whether those three units legitimately cannot run without a compositor, or are genuinely
broken on a clean machine, is not answerable from the run log.
Expected
clean machineis green onmain, and goes red only when a change actually breaks a clean install —so it can gate again.
Area
CI /
doctor.sh/ the component install chain.Related: #4 (introduced the workflow), #8 (evidence gathered in its comment)
🧠 Brainstorm
Problem / context
clean-machine.ymlwas added in #4 with an explicit rationale: "Nothing ever ran install.sh anywherebut the one laptop, and that is exactly how two 'nobody wired the startup' bugs survived." It worked —
it found a third such bug immediately. But the run was never brought back to green, so the signal was
lost the moment it was produced: five consecutive red runs later, the check carries no information,
and the one PR open against the repo had to be merged past it by hand.
The two MISSes are different in kind and must not be treated as one:
gets a dynamic-wallpaper config pointing at four files nobody ships. It is not about CI at all; CI
is merely the only place it is visible.
legitimately cannot start without a compositor. The run log does not say, and guessing which is
precisely the failure mode ci: prove install.sh and doctor.sh on a clean machine #4 was written to end.
Approaches
A. Gate the failing checks off on CI (
MACARCHY_NO_HARDWARE-style skip) and move on.Green immediately, one line per check. But it would suppress the wallpaper MISS, which is a real bug
on real machines — it would turn the one workflow that found a genuine defect into one that is
configured not to. Rejected.
B. Fix the defects, leave the workflow alone.
Honest, but blocked out of the gate: the failed-units MISS cannot be fixed before it can be read, and
nothing in the run log says why those units failed.
C. Diagnose first, then fix, then let the check gate again. (recommended)
Make CI say why a unit failed (Task 1), which costs a handful of lines and permanently improves
every future red run. Then fix the wallpaper defect at its source (Task 2), and dispose of the three
units on the evidence Task 1 produces (Task 3) — either a real fix, or a narrow documented skip for
what genuinely needs a compositor, decided from a journal rather than from a guess.
Recommendation
C. The order is the point: Task 1 is what turns Task 3 from speculation into a decision, and it is
the cheapest of the three. Approach A is explicitly rejected — a skip is only acceptable for something
proven to need hardware CI does not have, which is what Task 1 establishes and Task 3 applies.
📋 Spec
Goal
clean machinegreen onmainand meaningful as a gate, with both MISSes resolved on their merits —no MISS silenced that a real machine would also report.
Scope
tests/clean-machine.sh— dump the journal of every failed user unit beforedoctor.shdecides.Non-goals
doctor.sh's verdicts on a real laptop. The doctor is reporting the truth; this issueis about making the truth actionable and then making it green.
Design
flowchart TD A[install.sh twice] --> B[dump journal of each failed user unit] B --> C[doctor.sh decides] C -->|wallpaper MISS| D[seeded default names a shipped set] C -->|units MISS| E{journal says why} E -->|needs a compositor| F[narrow skip, reason stated] E -->|genuinely broken| G[fix the unit]The wallpaper fix has two viable shapes, and Task 2 picks one on evidence rather than in advance:
either apple-glass ships the
26-tahoe-beach-*set it is already assumed to own, orthe seeded default names a set apple-glass does ship (
1-sequoia-duskand friends). The second issmaller and stays inside this repo's dependency direction; the first is right if those wallpapers were
always meant to be part of the theme. Whichever lands, the check that proves it is the same.
Edge cases
systemctl --user --failedalreadyreflects only the current state.
|| true), and must not run atall when nothing failed.
macarchy-failed@<unit>.serviceinstances fold onto their target indoctor.sh:63; the dump mustuse the folded name, not the instance.
Assumptions
unverified, and Task 1 exists precisely to settle it. Task 3 is written to accept either answer.
26-tahoe-beach-*.jpgon the maintainer's laptop came from local history, not from any repo inREPOS— established byfindoverapple-glassreturning nothing.Acceptance criteria
clean machineis green onmain—doctor.shreports0 missing.macos-dynamic-wallpaper statusexits 0 with nowallpaper not found.skipline, and still reportsMISSon a reallaptop where the condition does not hold.
tests/clean-machine.shtwice in a row is still idempotent — the second run adds no new MISS.Testing decisions
Seams under test:
tests/clean-machine.sh's stdout and exit code (the whole workflow step is onescript, already the CI seam), and
doctor.sh'sMISS/oklines — the same text-level seamtests/test_doctor_notify.shandtests/test_doctor_touchbar_modules.shalready assert through.Prior art:
tests/test_doctor_touchbar_modules.sh— tempHOME, PATH stubs, a stubbedjournalctlreplaying a fixture.A good test here: stub
systemctl --user --failedto report one unit, assert the journal for thatunit reaches stdout and that a run with nothing failed emits no dump.
Out of scope
clean machinea required check — that is a branch-protection decision for the owner once itis reliably green.
26-tahoe-*wallpapers' provenance or licensing.🛠️ Implementation plan
Goal:
clean machinegreen onmainand gating again, with both MISSes resolved on their merits.Architecture: plain bash —
install.sh,doctor.sh,tests/*.sh; the suites are hermetic (tempHOME+ PATH stubs) and CI runstests/test_*.shplusbash -n.Tech stack: bash 5,
gh, GitHub Actions onubuntu-24.04-arm.Seams under test:
tests/clean-machine.sh's stdout and exit code, anddoctor.sh'sMISS/oklines — the text-level seam the existing doctor suites already assert through.Global constraints
HOME, PATH stubs, no compositor, no Apple hardware. CI runstests/test_*.shby glob — a new suite must match it.bash -nmust pass oninstall.sh,boot.sh,doctor.shandtests/*.sh.skipstates its reason and is gated on a condition that is false on the laptop.fix.Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>.Task 1: CI says WHY a user unit failed
Files: modify
tests/clean-machine.sh; testtests/test_clean_machine_journal.sh(new).Interfaces: after the
install.shruns and beforedoctor.sh, for each unit insystemctl --user --failed --no-legend --plain, print a labelledjournalctl --user -u <unit> --no-pager -n 40block. Foldsmacarchy-failed@<u>.serviceonto<u>the same waydoctor.sh:63does.tests/test_clean_machine_journal.sh(seam: the script's stdout) — stubsystemctlto report one failed unit andjournalctlto emit a marker line; assert the marker and the unit name both reach stdout.systemctl --user --failedreports nothing, assert no dump block is emitted.bash tests/test_clean_machine_journal.sh→ FAIL (no dump exists yet).tests/clean-machine.sh,|| trueon the journal call so a unit with no journal cannot fail the step.bash -nclean on everytests/*.sh.fix(ci): dump the journal of every failed user unit on a clean machine.clean machinerun, and record the three units' journals in a comment on this issue — Task 3 is written against that output.Task 2: a fresh install names wallpapers it actually installs
Files: modify whichever of
macos-dynamic-wallpaper's seeded default orapple-glass/backgrounds/the evidence selects (cross-repo — see note); modifytests/clean-machine.shonly if a new assertion is needed.Interfaces: after a clean
install.sh,macos-dynamic-wallpaper statusexits 0 and every path in the seeded config exists.26-tahoe-beach-*set —git loginapple-glassfor a removal, and the provenance of the copies in~/.config/omarchy/backgrounds/apple-glass/. Record the finding in a comment on this issue.tests/clean-machine.shso awallpaper not foundindoctor.sh's output fails the step with that line quoted (seam: the script's exit code + stdout).tests/clean-machine.shlocally against a tempHOME→ FAIL on the missing wallpaper.macarchy-install, open the PR there and link it here — do not vendor another repo's assets into this one.fix(install): seed a dynamic-wallpaper default whose files are installed.Task 3: dispose of the three failing units on Task 1's evidence
Files: modify
doctor.shand/or the failing units' installers, per the journals; testtests/test_doctor_notify.sh(extend).Interfaces:
doctor.shreports0 missingon a clean runner without hiding anything a laptop would report.doctor.shprintsskipwith a stated reason when the gating condition is set, andMISSwhen it is not (seam:doctor.sh's output lines).MACARCHY_NO_HARDWARE's existing shape — a named condition CI sets and the laptop never does.bash -n→ PASS.fix(doctor): resolve the user units that fail on a clean machine.clean machineis green on the PR, then say in the PR body that the check is ready to be made required.