diff --git a/core/system/input-method.nix b/core/system/input-method.nix index f338f9b..f1c8c64 100644 --- a/core/system/input-method.nix +++ b/core/system/input-method.nix @@ -11,12 +11,15 @@ in i18n.inputMethod = { enable = true; type = "fcitx5"; - fcitx5.addons = with pkgs; [ - fcitx5-mozc # Japanese - kdePackages.fcitx5-chinese-addons - fcitx5-table-extra # Hanyu/Cangjie/etc. - fcitx5-gtk # GTK4/3 client - ]; + fcitx5 = { + waylandFrontend = true; + addons = with pkgs; [ + fcitx5-mozc # Japanese + kdePackages.fcitx5-chinese-addons + fcitx5-table-extra # Hanyu/Cangjie/etc. + fcitx5-gtk # GTK4/3 client + ]; + }; }; }; } diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index e476666..bd533c3 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -19,9 +19,7 @@ Guardrails (apply when adding anything): ### Now (ready to pick up) -- **Ironclad: Multi-Monitor Integrity.** Verify Hyprland, Waybar, and Walker behavior on dual-screen setups. Ensure launchers follow the cursor and the bar handles secondary monitors gracefully. -- **Ironclad: Input Method (Fcitx5) Functional Pass.** Prove that non-ASCII input (Pinyin/Mozc) is functional in the live VM. Fix any Wayland-specific D-Bus or environment issues. -- **Ironclad: Overlap & Conflict Proofing.** Verify that manual Nix overrides in `home.nix` correctly and consistently take precedence over the machine-managed `nomarchy-state.nix`. +_(empty — all entries shipped or moved to Later)_ ### Next (bigger lifts that build on Now) @@ -179,6 +177,9 @@ Pillar is **done** when every component has had a live VM pass and the roadmap c (Move items here when they land — keep them brief, link the commit/PR.) +- _2026-05-31_ — **Ironclad: Overlap & Conflict Proofing complete.** Verified that manual Nix overrides in `home.nix` take precedence over UI choices without causing evaluation errors. **Fixed:** Updated `nomarchy-sync-nix-state` and the installer to wrap all machine-generated values in `nomarchy-state.nix` with `lib.mkDefault`. This ensures a user can manually set `nomarchy.theme = "catppuccin"` in their config, safely overriding the UI state without triggering "conflicting definition values" errors in the module system. +- _2026-05-31_ — **Ironclad: Input Method (Fcitx5) Functional Pass complete.** Verified that non-ASCII input (Pinyin/Mozc) is functional in the live VM. **Fixed:** Enabled `i18n.inputMethod.fcitx5.waylandFrontend = true` in `core/system/input-method.nix` to properly bind Fcitx5 to the Wayland text-input protocol, resolving missing environment variable issues and ensuring the candidate window renders correctly in Hyprland. +- _2026-05-31_ — **Ironclad: Multi-Monitor Integrity complete.** Verified Hyprland, Waybar, and Walker behavior on dual-screen setups (simulated via dual `virtio-vga` VM devices). **Fixed:** Removed a hardcoded `"output": "DP-2"` parameter from the `summer-day` Waybar configuration, ensuring the bar spawns seamlessly across all connected monitors. Confirmed Walker inherently follows the active monitor as expected. - _2026-05-31_ — **Ironclad: Offline Resilience complete.** Audited the system for network-induced hangs by booting a live VM with `-net none`. **Fixed:** `nomarchy-upload-log` (added a 5s connect timeout to `curl` to fail fast when ix.io is unreachable) and `nomarchy-update-available` (added a fast-fail ping check so Waybar doesn't hang executing `nix flake metadata` while offline). **Restored:** recreated `nomarchy-update` (syncs the local git repo and calls `nomarchy-sys-update`) and `nomarchy-update-time` (restarts `systemd-timesyncd`), which were referenced in the menu but missing from the filesystem. The system now remains fully responsive without internet access. - _2026-05-31_ — **Flake Update logic fixed & Rolling Release path established.** Rewrote `nomarchy-update` to properly interact with the downstream `flake.nix` inputs. Instead of attempting a `git pull`, it now strips the initial installation pin (`?rev=`) to seamlessly transition the user to a rolling release, and then runs `nix flake update` to bump `flake.lock`. Rewrote `nomarchy-update-available` to correctly query the upstream git repository and compare its `HEAD` against the local lockfile, ensuring the Waybar update icon only appears when an actual update is pending. - _2026-05-31_ — **Deep Runtime Polish: State-Sync Stress Test complete.** Verified the robustness of the hybrid declarative state system (`nomarchy-state.nix`) via an automated chaos test in a live VM (250 parallel writes across 5 concurrent workers). **Bug fixed:** identified and resolved a critical race condition where the Nix sync script was being called outside the `flock` lock in `nomarchy-state-write`. Moving the sync inside the protected block ensured atomic updates to both JSON and Nix state files. Verification confirmed 100% integrity and zero desyncs under heavy load. diff --git a/features/desktop/waybar/themes/summer-day/config.jsonc b/features/desktop/waybar/themes/summer-day/config.jsonc index 47cd663..f651bac 100755 --- a/features/desktop/waybar/themes/summer-day/config.jsonc +++ b/features/desktop/waybar/themes/summer-day/config.jsonc @@ -6,7 +6,6 @@ "height": 60, "layer": "top", "position": "top", - "output": "DP-2", "spacing": 15, "modules-left": ["custom/launcher", "clock", "clock#date"], "modules-center": ["wlr/workspaces"], diff --git a/features/scripts/utils/nomarchy-sync-nix-state b/features/scripts/utils/nomarchy-sync-nix-state index 1eff6fd..01a7d23 100755 --- a/features/scripts/utils/nomarchy-sync-nix-state +++ b/features/scripts/utils/nomarchy-sync-nix-state @@ -33,30 +33,31 @@ fi echo "# DO NOT EDIT MANUALLY - Managed by Nomarchy scripts." echo "# This file mirrors your UI choices (theme, font, etc.) into the declarative" echo "# Nix configuration. It is imported by your home.nix." + echo "{ lib, ... }:" echo "{" echo " nomarchy = {" # Core UI strings - echo " theme = \"$(jq -r '.theme // empty' "$STATE_JSON")\";" - echo " fonts.monospace = \"$(jq -r '.font // empty' "$STATE_JSON")\";" - echo " panelPosition = \"$(jq -r '.panelPosition // empty' "$STATE_JSON")\";" - echo " wallpaper = \"$(jq -r '.wallpaper // empty' "$STATE_JSON")\";" + echo " theme = lib.mkDefault \"$(jq -r '.theme // empty' "$STATE_JSON")\";" + echo " fonts.monospace = lib.mkDefault \"$(jq -r '.font // empty' "$STATE_JSON")\";" + echo " panelPosition = lib.mkDefault \"$(jq -r '.panelPosition // empty' "$STATE_JSON")\";" + echo " wallpaper = lib.mkDefault \"$(jq -r '.wallpaper // empty' "$STATE_JSON")\";" # Hyprland layout (numbers) echo " hyprland = {" - echo " scale = \"$(jq -r '.hyprland.scale // "auto"' "$STATE_JSON")\";" - echo " gaps_in = $(jq -r '.hyprland.gaps_in // 5' "$STATE_JSON");" - echo " gaps_out = $(jq -r '.hyprland.gaps_out // 10' "$STATE_JSON");" - echo " border_size = $(jq -r '.hyprland.border_size // 2' "$STATE_JSON");" + echo " scale = lib.mkDefault \"$(jq -r '.hyprland.scale // "auto"' "$STATE_JSON")\";" + echo " gaps_in = lib.mkDefault $(jq -r '.hyprland.gaps_in // 5' "$STATE_JSON");" + echo " gaps_out = lib.mkDefault $(jq -r '.hyprland.gaps_out // 10' "$STATE_JSON");" + echo " border_size = lib.mkDefault $(jq -r '.hyprland.border_size // 2' "$STATE_JSON");" echo " };" # Toggles (booleans) echo " toggles = {" - echo " suspend = $(jq -r '.suspend // true' "$STATE_JSON");" - echo " screensaver = $(jq -r '.screensaver // true' "$STATE_JSON");" - echo " idle = $(jq -r '.idle // true' "$STATE_JSON");" - echo " nightlight = $(jq -r '.nightlight // false' "$STATE_JSON");" - echo " waybar = $(jq -r '.waybar // true' "$STATE_JSON");" + echo " suspend = lib.mkDefault $(jq -r '.suspend // true' "$STATE_JSON");" + echo " screensaver = lib.mkDefault $(jq -r '.screensaver // true' "$STATE_JSON");" + echo " idle = lib.mkDefault $(jq -r '.idle // true' "$STATE_JSON");" + echo " nightlight = lib.mkDefault $(jq -r '.nightlight // false' "$STATE_JSON");" + echo " waybar = lib.mkDefault $(jq -r '.waybar // true' "$STATE_JSON");" echo " };" echo " };" diff --git a/installer/install.sh b/installer/install.sh index b84ebf7..ce974dd 100755 --- a/installer/install.sh +++ b/installer/install.sh @@ -1876,24 +1876,25 @@ EOF # DO NOT EDIT MANUALLY - Managed by Nomarchy scripts. # This file mirrors your UI choices (theme, font, etc.) into the declarative # Nix configuration. It is imported by your home.nix. + { lib, ... }: { nomarchy = { - theme = \"\${s.theme}\"; - fonts.monospace = \"\${s.font}\"; - panelPosition = \"\${s.panelPosition}\"; - wallpaper = \"\${s.wallpaper}\"; + theme = lib.mkDefault \"\${s.theme}\"; + fonts.monospace = lib.mkDefault \"\${s.font}\"; + panelPosition = lib.mkDefault \"\${s.panelPosition}\"; + wallpaper = lib.mkDefault \"\${s.wallpaper}\"; hyprland = { - scale = \"\${s.hyprland.scale}\"; - gaps_in = \${toString s.hyprland.gaps_in}; - gaps_out = \${toString s.hyprland.gaps_out}; - border_size = \${toString s.hyprland.border_size}; + scale = lib.mkDefault \"\${s.hyprland.scale}\"; + gaps_in = lib.mkDefault \${toString s.hyprland.gaps_in}; + gaps_out = lib.mkDefault \${toString s.hyprland.gaps_out}; + border_size = lib.mkDefault \${toString s.hyprland.border_size}; }; toggles = { - suspend = \${lib.boolToString s.suspend}; - screensaver = \${lib.boolToString s.screensaver}; - idle = \${lib.boolToString s.idle}; - nightlight = \${lib.boolToString s.nightlight}; - waybar = \${lib.boolToString s.waybar}; + suspend = lib.mkDefault \${lib.boolToString s.suspend}; + screensaver = lib.mkDefault \${lib.boolToString s.screensaver}; + idle = lib.mkDefault \${lib.boolToString s.idle}; + nightlight = lib.mkDefault \${lib.boolToString s.nightlight}; + waybar = lib.mkDefault \${lib.boolToString s.waybar}; }; }; }