docs(dev): the Mac runbook names the consolidated packages, paths and version

macos-hand-check-plan.md: a note at the top says the text was changed for the cutover stack
and not run; the build command also names komorebi-client and komorebi-macos; the line
about never mixing -p komorebic-macos with -p komorebic is replaced by a line saying the
shims are gone; the example config is docs/macos/komorebi.example.json, the schemas are
schemas/macos/schema.json and schemas/macos/schema.bar.json, and the expected version is
`komorebi 0.2.0` from crates/komorebi-version.
macos-handcheck.md (the older list): a paragraph at the top maps the old names to the
current ones and points at the plan; the Mini run and the bar file path get a "now" note.

The runbook has no flake attributes, so none are left for flake-one. Not run: nothing in
this revision was executed, on a Mac or elsewhere; the package names were checked against
the workspace manifests (komorebi is komorebi-daemon, komorebi-macos is the library).
This commit is contained in:
LGUG2Z committed 2026-11-05 15:03:27 -08:00
1 parent 1b3178cede
commit 4ca58a08ab
2 files changed
+16 -10

No files matched your search

+13 -7
View File
@@ -7,6 +7,11 @@ run on a Mac as a daemon.** What did run, on a Mac Mini: `cargo build`, `clippy
passed, 0 failed, 1 ignored at candidate 8) and the nix builds of `komorebi`, `komorebic`, `komorebi-bar` and the
darwin checks. No window has been tiled, hidden, focused or bordered by these builds.
Cutover stack (`wip-cutover`): the commands and paths below name the consolidated layout (the shim packages
are gone, `komorebi-for-mac/` is `komorebi-macos/`, `docs/macos/` and `schemas/macos/`) and the version is
0.2.0. The text was changed, not run: no command of this runbook was executed on a Mac after the rename.
The nix commands, if a step has any, still name the old flake attributes until the one flake lands.
How to read an item: **Steps**, **Expect**, **Stop / roll back**, **Introduced by** (jj bookmark or change id;
`jj log -r <id>` in the repository, commit ids move when a revision is rewritten). Items marked `[2 displays]`,
`[trackpad]`, `[physical]` need a second screen, a trackpad gesture, or someone to plug cables; `[2nd person]` is
@@ -49,16 +54,17 @@ auto-started daemon unless you disabled autostart yourself first.
**0.1 Build and test.** From the repository root, with a `.git` checkout (or `COMMIT_HASH=dev`):
```sh
cargo build --locked -p komorebi -p komorebic -p komorebi-bar
cargo build --locked -p komorebi -p komorebic -p komorebi-bar -p komorebi-client -p komorebi-macos
cargo test --locked -p komorebi-macos -p komorebic -p komorebi-client -p komorebi-bar-core -p komorebi-bar -p komorebi-core -p komorebi-config -p komorebi-protocol
cargo clippy --locked -p komorebi -p komorebi-macos -p komorebic -p komorebi-client -p komorebi-bar -p komorebi-bar-core --all-targets -- -D warnings
```
Never name `-p komorebic-macos` together with `-p komorebic` (same binary name). Expect: 0 failures (the Mini
`-p komorebi` is the package in `komorebi-daemon/` (the binary), `-p komorebi-macos` its macOS library; the
shims `komorebic-macos`, `komorebi-client-macos` and `komorebi-bar-macos` no longer exist. Expect: 0 failures (the Mini
saw 665 passed, 0 failed, 1 ignored). Roll back: nothing to do; if a test fails, stop and report its name.
**0.2 A clean config and data directory.** Make an empty directory for the run, put a minimal
`komorebi.json` in it (copy `komorebi-for-mac/docs/komorebi.example.json`), and set `KOMOREBI_CONFIG_HOME` to it.
`komorebi.json` in it (copy `docs/macos/komorebi.example.json`), and set `KOMOREBI_CONFIG_HOME` to it.
The data directory (socket, logs) is the user's `~/Library/Application Support/komorebi`, which this variable does
not change; use another Mac or a throwaway macOS user if you cannot guarantee the live daemon is not running.
Expect: `pgrep -l komorebi` prints nothing before you start.
@@ -77,8 +83,8 @@ The riskiest changes: the daemon now starts from a shared `daemon::run`, the com
subscriber push and event channel are the shared transport, and `SocketMessage` is the shared enum.
**1.1 Start and stop.** Steps: start the daemon (0.3); in another terminal `target/debug/komorebic state | head`,
`komorebic global-state | head`, `komorebic --version`, `target/debug/komorebi --version` (expect `komorebi 0.1.0`
with the macOS version crate). Then Ctrl-C the daemon. Expect: state is JSON; the daemon logs the restore of all
`komorebic global-state | head`, `komorebic --version`, `target/debug/komorebi --version` (expect `komorebi 0.2.0`,
from `crates/komorebi-version`). Then Ctrl-C the daemon. Expect: state is JSON; the daemon logs the restore of all
windows and exits (code 130), all windows are back where they were, `komorebi.sock` is gone. Stop: Ctrl-C; if the
daemon does not exit, `kill` the pid you started (not `pkill`). Introduced by: `wip-u-pkg2` (one `komorebi`
package, `1326f041`) and the shared transport revisions `nvwvptpv`, `ywwwwpwm`, `kzynysto`.
@@ -202,7 +208,7 @@ after it. Introduced by: `mquxryqt` (settings S5).
**5.3 Schema and config loading (H-rows).** A real `komorebi.json` of yours loads with no new warning and every key
works (borders, padding, animations, scrolling, rules, workspaces); `komorebic static-config-schema` equals
`komorebi-for-mac/schema.json`. Introduced by: `kvtvnouo`, `stxmqnop` (StaticConfig from `komorebi-config`).
`schemas/macos/schema.json`. Introduced by: `kvtvnouo`, `stxmqnop` (StaticConfig from `komorebi-config`).
## Block 6. The rest of the daemon walk-through (about 60 min)
@@ -230,7 +236,7 @@ The bar is now the `komorebi-bar` package (module `macos`) over `komorebi-bar-co
`starship-battery` 0.11.
**7.1 Renders.** `target/debug/komorebi-bar` against the running test daemon: workspaces, layout, CPU %, memory,
battery % and charging, date and the calendar icon, all sane. `komorebi-bar --schema | cmp - komorebi-for-mac/schema.bar.json`
battery % and charging, date and the calendar icon, all sane. `komorebi-bar --schema | cmp - schemas/macos/schema.bar.json`
is silent. Introduced by: `wip-u-pkg-mig` bar revisions (`7d4ea893`, `bdd811f2`), `nottqpms` and the bar-core hooks.
**7.2 Old state and the bar (H10).** `komorebic state > old.json` on the ORIGINAL build; start the new bar against
+3 -3
View File
@@ -2,13 +2,13 @@
> **Status (wip-cand4):** OPEN, for the user on a real Mac; only compile and unit tests have run on a Mac Mini, no macOS daemon behaviour has been observed; commands for the Mac are in [build-and-test.md](build-and-test.md).
Status: written by the `kfm` agent for the user, 2026-10-31. Nothing here has been run: macOS cannot be built, linked or tested on the Linux host, only type-checked through a fake C compiler (`tools/fast-check`). Every revision below is `type-checks, not run`. Revision ids are jj change ids (stable) with the commit id they had when this was written (commit ids change when a revision is rewritten; use `jj log -r <change id>`).
Status: written by the `kfm` agent for the user, 2026-10-31. Nothing here has been run: macOS cannot be built, linked or tested on the Linux host, only type-checked through a fake C compiler (`tools/fast-check`). Every revision below is `type-checks, not run`. Paths and names below are those of the time (written before the cutover stack): `komorebi-for-mac/` is now `komorebi-macos/`, its docs are `docs/macos/`, its schemas `schemas/macos/`, the shim packages are gone and every package is 0.2.0; the current runbook is [macos-hand-check-plan.md](macos-hand-check-plan.md). Revision ids are jj change ids (stable) with the commit id they had when this was written (commit ids change when a revision is rewritten; use `jj log -r <change id>`).
How to use it: build the unified (or, until they exist, the per-tree) macOS `komorebi`, `komorebic` and `komorebi-bar`, run `cargo test --workspace` on the Mac first (the 399+ unit tests have never run against these changes), then walk the sections in order. For before/after capture use `komorebi-recorder` against a build of the baseline `wip-main` ancestor `ff3711dc` and the tip. A section is done when the "look for" column is true.
## Status of the Mini runs (2026-10-31)
The real-Mac runs so far (Mac Mini, rustc and clippy 1.93, tip a35573d8) are **compile and unit tests only**: `cargo test --workspace` in komorebi-for-mac passed (daemon 366 passed, 1 ignored; 368 total, 0 failed) and clippy `-D warnings` was clean apart from the two items fixed afterwards. Nothing was run as a daemon: no focus, tiling, borders, animations or bar rendering has been observed on the Mini. Every walk-through item below is still open.
The real-Mac runs so far (Mac Mini, rustc and clippy 1.93, tip a35573d8) are **compile and unit tests only**: `cargo test --workspace` in komorebi-for-mac (now `komorebi-macos/`) passed (daemon 366 passed, 1 ignored; 368 total, 0 failed) and clippy `-D warnings` was clean apart from the two items fixed afterwards. Nothing was run as a daemon: no focus, tiling, borders, animations or bar rendering has been observed on the Mini. Every walk-through item below is still open.
## Prioritised checks from the independent review (H1-H12)
@@ -142,7 +142,7 @@ Do each with the baseline build and the tip build and compare (or record with `k
## D. Bugs noticed, not fixed here
A. **Possible deadlock, main queue against the window-manager lock** (`docs/dev/seam.md` section 3.3, by reading only, never reproduced). A thread holding the WM lock calls a blocking main-queue dispatch (`destroy_all_borders` at process_event.rs lines about 128/139, process_command.rs, `retile_all`; `hide_borders_on` in window_manager.rs; `activate_finder` in process_event.rs) while the monitor reconciliator has dispatched a closure to main that itself takes the WM lock (monitor_reconciliator.rs about 106 and 383). Then the event thread waits for main, main waits for the lock. `parking_lot`'s deadlock detector cannot see it (the dispatch is a semaphore). Window of exposure: a display change at the instant of one of those events. Structural fix: no closure that runs on main may take the WM lock (or dispatch to main only after the lock is dropped). How to provoke it: spam `komorebic retile` / workspace switches (with ghosts) while plugging or unplugging a monitor; the symptom is a daemon that answers no command (`komorebic state` hangs).
B. **cmd.exe and explorer.exe in the macOS bar** (`komorebi-for-mac/komorebi-bar/src/os.rs`, `BarPlatform::open_system_tool`): the battery click spawns `cmd.exe` (power settings), the update click spawns `explorer.exe` with the release URL; neither exists on macOS. The same file's CPU (task manager) and network settings tools should be Activity Monitor and System Settings. The fix is one function in that file; it was preserved on purpose during the bar move.
B. **cmd.exe and explorer.exe in the macOS bar** (`komorebi-for-mac/komorebi-bar/src/os.rs`, now `komorebi-bar/src/macos/os.rs`, `BarPlatform::open_system_tool`): the battery click spawns `cmd.exe` (power settings), the update click spawns `explorer.exe` with the release URL; neither exists on macOS. The same file's CPU (task manager) and network settings tools should be Activity Monitor and System Settings. The fix is one function in that file; it was preserved on purpose during the bar move.
C. **Update widget refresh thread polls the Windows repo's GitHub API** on macOS too (update.rs has a second URL that does not go through the hook), and the macOS update link is `.../releases/v..` built for the Windows repo.
D. **Other raw AX sites remain outside `Window`**: window.rs (38 inside `Window`/`AdhocWindow`, expected), application.rs 11 (`Application`, not a window), process_event.rs 7 (events that hand over a bare element: `window_id` of an element, the tab check `AccessibilityApi::window_id(&window.element.0)`), animation/animator.rs 6 (lane threads hold `WindowHandle` clones of the element), border_manager 7 (observers on tracked elements), window_manager.rs 4 (timeouts list holds elements, `window_id` of an element), reaper.rs 2 (`notify_if_gone` takes an element so lanes can use it), input_event_listener.rs 1, process_command.rs 1. They need either an id to AX registry (step 11(ii), not started) or a `WindowHandle` type; they were left alone because routing them changes who owns the element.
D2. **Step 11(ii) status.** Done: the id registry (`ax_registry`, over the tested `komorebi_backend::Registry`), populated at `Window::new`, kept in step for native tabs, emptied on death, reap and application quit; `MacosBackend` resolves ids through it. NOT done, on purpose, because each needs a decision that cannot be verified without a Mac: (a) the animator lanes (`WindowHandle`) keep their own snapshot of the element: a lane must keep writing to the element of the move it was given even if a tab swap replaced the registry entry, and replacing the snapshot by a lookup per write changes what a late write hits; (b) borders keep `tracking_element` (observer sources are added and removed on that exact element, on main); (c) `reaper::notify_if_gone` and the window manager's live-resize `timeouts` list take elements, including application elements, that are not registry entries; (d) `application.rs` is the application, not a window. (e) The model (`Window`, containers, workspaces) still holds `Window` values, not bare `WindowId`s: that is step 11(iii), after steps 8-9. A stale registry id answers `Error::WindowGone` (no panic); a window that was deserialised from state (default system-wide element) is never registered.