From 47f29f9fa9275c78c86f39ec4ece3534a1522c16 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Thu, 20 Aug 2026 21:33:57 -0400 Subject: [PATCH] Stop describing a desktop this repository does not install Phase 5. The README advertised two desktops that coexist -- GNOME with Forge, Dash-to-Dock, Openbar and Vitals, alongside Hyprland -- and nothing in setup/ installed or configured any of the first one. Panama configures one desktop, and now says so. config/dot/forge is deleted along with its entry in link-dotfiles. It was the hedge from when the GNOME session was still the fallback and Hyprland was being built beside it; the hedge has been paid off. Nine files, six of which were Forge's own editor backups that should never have been committed. Searching for the rest of GNOME found nothing else to cut, which is recorded in the spec so nobody goes looking again. change-settings never enabled an extension. The mentions of Dash-to-Dock, Openbar and Vitals through the shell are comments saying what a component was modelled on -- which intellihide behaviour the dock reproduces, where a colour came from -- and DESKTOP-PARITY.md is the table of what replaced what. That is provenance, and it is the reason those components behave the way they do. Vitals in services/ is Panama's own bar service and merely shares a name with the extension it replaced. The handoff panel list was wrong in two places. It named Wacom, which nothing hands off to, and Region, which is a subpage of System rather than a panel. The nine real ones are read off the call sites and the allow-list that gates them. The spec said it, the comment on gnome-control-center repeated it, and the README would have made it three. One test gap turned up and is closed. The assets contract caught a directory under config/dot/ that nothing links, but not the inverse: a name left in the dirs array with nothing behind it, which makes link-dotfiles point ~/.config/ at a path that does not exist. Deleting Forge is the exact move that introduces that, and nothing would have failed if the array entry had been left. A dangling symlink is worse than a missing one, because everything that looks there finds something. Verified by putting the entry back and watching it fail. The audit of docs/settings.md this phase asked for needed nothing: it is generated from PreferenceSchema.qml, a contract already fails when it goes stale, and it carries no claim about GNOME or Forge. The README gained the section it was missing instead -- the 121 contracts under tests/ were the main safety net in this repository and went entirely unmentioned in it. Claude-Session: https://claude.ai/code/session_01NvgBuSWB5sE43yWmg21ozj --- README.md | 58 +++++- .../dot/forge/config/.windows.json.~260c6b69 | 72 ------- .../dot/forge/config/.windows.json.~318f7cf9 | 72 ------- .../dot/forge/config/.windows.json.~38323208 | 72 ------- .../dot/forge/config/.windows.json.~42767d6d | 72 ------- .../dot/forge/config/.windows.json.~63ed4469 | 72 ------- .../dot/forge/config/.windows.json.~68bf2ae6 | 72 ------- config/dot/forge/config/windows.json | 76 ------- .../dot/forge/stylesheet/forge/stylesheet.css | 190 ------------------ .../forge/stylesheet/forge/stylesheet.css.bak | 190 ------------------ .../2026-08-20-panama-fresh-install-design.md | 33 ++- setup/packages/desktop-packages | 6 +- setup/scripts/link-dotfiles | 13 +- tests/quickshell/declared-assets-contract | 22 ++ 14 files changed, 114 insertions(+), 906 deletions(-) delete mode 100644 config/dot/forge/config/.windows.json.~260c6b69 delete mode 100644 config/dot/forge/config/.windows.json.~318f7cf9 delete mode 100644 config/dot/forge/config/.windows.json.~38323208 delete mode 100644 config/dot/forge/config/.windows.json.~42767d6d delete mode 100644 config/dot/forge/config/.windows.json.~63ed4469 delete mode 100644 config/dot/forge/config/.windows.json.~68bf2ae6 delete mode 100644 config/dot/forge/config/windows.json delete mode 100644 config/dot/forge/stylesheet/forge/stylesheet.css delete mode 100644 config/dot/forge/stylesheet/forge/stylesheet.css.bak diff --git a/README.md b/README.md index 9f65cd9..6db8f4b 100644 --- a/README.md +++ b/README.md @@ -38,19 +38,27 @@ not written down anywhere. Existing configs are moved to `config/old/` rather than overwritten. -## Desktops +## The desktop -Panama configures **two** desktops that coexist. Both sessions stay available in -GDM, so you can switch back and forth while you settle in. +Hyprland, with a shell written from scratch. It began as a replacement for a +GNOME session — Forge for tiling, Dash-to-Dock, Openbar, Vitals — and was built +to reproduce it closely enough that muscle memory transferred: same keybinds, +same panel contents, same dock, same Tokyo Night Moon palette. -### GNOME -The original setup: Forge for tiling, Dash-to-Dock, Openbar, Vitals, -AppIndicator support. Configured through `config/dot/forge/` and gsettings. +That is history now rather than a second option. Panama installs and configures +one desktop, and the GNOME session it grew out of is neither installed nor +configured here. What each piece replaced is recorded in +[`config/dot/hypr/DESKTOP-PARITY.md`](config/dot/hypr/DESKTOP-PARITY.md) and in +the comments of the components themselves, because knowing what a thing was +modelled on explains why it behaves the way it does. -### Hyprland -A from-scratch replacement built to reproduce the GNOME setup closely enough -that muscle memory transfers — same keybinds, same panel contents, same dock, -same Tokyo Night Moon palette. +GNOME is not gone from the machine: `gnome-control-center` is a declared +dependency, and Panama's own Settings hands off to it for the panels it +deliberately does not own — Online Accounts, Color, Sound, Network, Keyboard, +Privacy, Wellbeing, Accessibility, and System for users, date and time, region +and remote desktop. The allow-list in +[`services/SystemSettings.qml`](config/dot/quickshell/services/SystemSettings.qml) +is what decides; anything not on it is a panel Panama owns itself. | Piece | What it is | |---|---| @@ -75,8 +83,36 @@ config/ bash/ .bashrc, aliases, env (env is gitignored) copy/ Files copied verbatim over / (needs sudo) dot/ Symlinked into ~/.config + firefox/ Vendored Firefox chrome, linked into the browser profile + local/ Icons and the cursor theme, linked into ~/.local/share old/ Backups of whatever was replaced (gitignored) + wallpapers/ Copied into ~/Pictures/Wallpapers when absent setup/ - packages/ One package per line + packages/ One package per line; extras/ holds the optional categories scripts/ Run in order by ./install +tests/ Contracts. See below +docs/ Settings reference, and the design specs behind the work +``` + +## Tests + +121 of them, under `tests/`, and each is a plain executable you can run on its +own: + +```sh +bash tests/setup/interview-contract +``` + +They are called contracts rather than unit tests because that is what they are: +each one pins a decision that was expensive to get right and is cheap to undo by +accident. Most read or measure the real thing — launching a shell to measure a +surface's geometry, standing stub commands on `PATH` to see what a stage would +have installed, running a script against a throwaway `HOME` — rather than +asserting things about source text, because the bugs worth catching here have all +been ones that source text looked fine for. + +``` +tests/setup/ The installer: the interview, package lists, hardware, extras +tests/quickshell/ The shell and its settings pages +tests/hypr/ The compositor config ``` diff --git a/config/dot/forge/config/.windows.json.~260c6b69 b/config/dot/forge/config/.windows.json.~260c6b69 deleted file mode 100644 index eb4b694..0000000 --- a/config/dot/forge/config/.windows.json.~260c6b69 +++ /dev/null @@ -1,72 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "Emulator", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/config/.windows.json.~318f7cf9 b/config/dot/forge/config/.windows.json.~318f7cf9 deleted file mode 100644 index eb4b694..0000000 --- a/config/dot/forge/config/.windows.json.~318f7cf9 +++ /dev/null @@ -1,72 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "Emulator", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/config/.windows.json.~38323208 b/config/dot/forge/config/.windows.json.~38323208 deleted file mode 100644 index eb4b694..0000000 --- a/config/dot/forge/config/.windows.json.~38323208 +++ /dev/null @@ -1,72 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "Emulator", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/config/.windows.json.~42767d6d b/config/dot/forge/config/.windows.json.~42767d6d deleted file mode 100644 index eb4b694..0000000 --- a/config/dot/forge/config/.windows.json.~42767d6d +++ /dev/null @@ -1,72 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "Emulator", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/config/.windows.json.~63ed4469 b/config/dot/forge/config/.windows.json.~63ed4469 deleted file mode 100644 index eb4b694..0000000 --- a/config/dot/forge/config/.windows.json.~63ed4469 +++ /dev/null @@ -1,72 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "Emulator", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/config/.windows.json.~68bf2ae6 b/config/dot/forge/config/.windows.json.~68bf2ae6 deleted file mode 100644 index eb4b694..0000000 --- a/config/dot/forge/config/.windows.json.~68bf2ae6 +++ /dev/null @@ -1,72 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "Emulator", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/config/windows.json b/config/dot/forge/config/windows.json deleted file mode 100644 index fc3c7db..0000000 --- a/config/dot/forge/config/windows.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "overrides": [ - { - "wmClass": "jetbrains-toolbox", - "mode": "float" - }, - { - "wmClass": "Com.github.amezin.ddterm", - "mode": "float" - }, - { - "wmClass": "Com.github.donadigo.eddy", - "mode": "float" - }, - { - "wmClass": "Conky", - "mode": "float" - }, - { - "wmClass": "Gnome-initial-setup", - "mode": "float" - }, - { - "wmClass": "org.gnome.Calculator", - "mode": "float" - }, - { - "wmClass": "gnome-terminal-preferences", - "mode": "float" - }, - { - "wmClass": "Guake", - "mode": "float" - }, - { - "wmClass": "zoom", - "mode": "float" - }, - { - "wmClass": "Bitwarden", - "mode": "float" - }, - { - "wmClass": "Hidamari", - "mode": "float" - }, - { - "wmClass": "com.mattjakeman.ExtensionManager", - "mode": "float" - }, - { - "wmClass": "Cider", - "mode": "float" - }, - { - "wmClass": "Ulauncher", - "mode": "float" - }, - { - "wmClass": "com.nextcloud.desktopclient.nextcloud", - "mode": "float" - }, - { - "wmClass": "mpv", - "mode": "float" - }, - { - "wmClass": "Spotify", - "mode": "float" - }, - { - "wmClass": "bitwarden", - "mode": "float" - } - ] -} \ No newline at end of file diff --git a/config/dot/forge/stylesheet/forge/stylesheet.css b/config/dot/forge/stylesheet/forge/stylesheet.css deleted file mode 100644 index aff744d..0000000 --- a/config/dot/forge/stylesheet/forge/stylesheet.css +++ /dev/null @@ -1,190 +0,0 @@ -.tiled { - color: rgba(236, 94, 94, 1); - opacity: 1; - border-width: 3px; -} - -.split { - color: rgba(255, 246, 108, 1); - opacity: 1; - border-width: 3px; -} - -.stacked { - color: rgba(247, 162, 43, 1); - opacity: 1; - border-width: 3px; -} - -.tabbed { - color: rgba(17, 199, 224, 1); - opacity: 1; - border-width: 3px; -} - -.floated { - color: rgba(180, 167, 214, 1); - border-width: 3px; - opacity: 1; -} - -.window-tiled-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-split-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -/* forge-36le: St does not paint an asymmetric (single-side) border when a - * border-radius is set, so the directional hint never rendered. Drop the radius - * on the one-edge variants; St paints a straight single-side border reliably. */ - -.window-split-horizontal { - border-left-width: 0; - border-top-width: 0; - border-bottom-width: 0; - border-radius: 0; -} - -.window-split-vertical { - border-left-width: 0; - border-top-width: 0; - border-right-width: 0; - border-radius: 0; -} - -.window-stacked-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-tabbed-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-tabbed-bg { - border-radius: 8px; -} - -.window-tabbed-tab { - background-color: rgba(54, 47, 45, 1); - border-color: rgba(98,160,234,0.6); - border-width: 1px; - border-radius: 8px; - color: white; - margin: 1px; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); -} - -.window-tabbed-tab-active { - background-color: rgb(98,160,234); - color: black; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); -} - -.window-tabbed-tab-close { - padding: 3px; - margin: 4px; - border-radius: 16px; - width: 16px; - background-color: #e06666; -} - -.window-tabbed-tab-icon { - margin: 3px; -} - -.window-floated-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-tilepreview-tiled { - border-width: 1px; - border-color: rgba(98,160,234,0.3); - border-style: solid; - border-radius: 14px; - background-color: rgba(98,160,234,0.2); -} - -.window-tilepreview-stacked { - border-width: 1px; - border-color: rgba(98,160,234,0.3); - border-style: solid; - border-radius: 14px; - background-color: rgba(98,160,234,0.2); -} - -.window-tilepreview-swap { - border-width: 1px; - border-color: rgba(162, 247, 43, 0.4); - border-style: solid; - border-radius: 14px; - background-color: rgba(162, 247, 43, 0.4); -} - -.window-tilepreview-tabbed { - border-width: 1px; - border-color: rgba(98,160,234,0.3); - border-style: solid; - border-radius: 14px; - background-color: rgba(98,160,234,0.2); -} - -/* Keybindings Cheatsheet Overlay */ - -.forge-cheatsheet { - background-color: #2d2d2d; - border-radius: 16px; - padding: 24px 32px; - border: 1px solid #4d4d4d; - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); -} - -.forge-cheatsheet-title { - font-size: 16px; - font-weight: bold; - color: #ffffff; - margin-bottom: 20px; - text-align: center; -} - -.forge-cheatsheet-category { - font-size: 13px; - font-weight: bold; - color: #78aeed; - margin-top: 16px; - margin-bottom: 8px; -} - -.forge-cheatsheet-row { - font-size: 12px; - color: #eeeeec; - margin: 4px 0; - padding: 2px 0; -} - -.forge-cheatsheet-key { - font-family: monospace; - font-weight: bold; - color: #f5c211; - min-width: 180px; -} - -.forge-cheatsheet-desc { - color: #d0cfcc; -} \ No newline at end of file diff --git a/config/dot/forge/stylesheet/forge/stylesheet.css.bak b/config/dot/forge/stylesheet/forge/stylesheet.css.bak deleted file mode 100644 index c80c7ac..0000000 --- a/config/dot/forge/stylesheet/forge/stylesheet.css.bak +++ /dev/null @@ -1,190 +0,0 @@ -.tiled { - color: rgba(236, 94, 94, 1); - opacity: 1; - border-width: 3px; -} - -.split { - color: rgba(255, 246, 108, 1); - opacity: 1; - border-width: 3px; -} - -.stacked { - color: rgba(247, 162, 43, 1); - opacity: 1; - border-width: 3px; -} - -.tabbed { - color: rgba(17, 199, 224, 1); - opacity: 1; - border-width: 3px; -} - -.floated { - color: rgba(180, 167, 214, 1); - border-width: 3px; - opacity: 1; -} - -.window-tiled-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-split-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -/* forge-36le: St does not paint an asymmetric (single-side) border when a - * border-radius is set, so the directional hint never rendered. Drop the radius - * on the one-edge variants; St paints a straight single-side border reliably. */ - -.window-split-horizontal { - border-left-width: 0; - border-top-width: 0; - border-bottom-width: 0; - border-radius: 0; -} - -.window-split-vertical { - border-left-width: 0; - border-top-width: 0; - border-right-width: 0; - border-radius: 0; -} - -.window-stacked-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-tabbed-border { - border-width: 3px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-tabbed-bg { - border-radius: 8px; -} - -.window-tabbed-tab { - background-color: rgba(54, 47, 45, 1); - border-color: rgba(98,160,234,0.6); - border-width: 1px; - border-radius: 8px; - color: white; - margin: 1px; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); -} - -.window-tabbed-tab-active { - background-color: rgb(98,160,234); - color: black; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); -} - -.window-tabbed-tab-close { - padding: 3px; - margin: 4px; - border-radius: 16px; - width: 16px; - background-color: #e06666; -} - -.window-tabbed-tab-icon { - margin: 3px; -} - -.window-floated-border { - border-width: 1px; - border-color: rgb(98,160,234); - border-style: solid; - border-radius: 14px; -} - -.window-tilepreview-tiled { - border-width: 1px; - border-color: rgba(98,160,234,0.3); - border-style: solid; - border-radius: 14px; - background-color: rgba(98,160,234,0.2); -} - -.window-tilepreview-stacked { - border-width: 1px; - border-color: rgba(98,160,234,0.3); - border-style: solid; - border-radius: 14px; - background-color: rgba(98,160,234,0.2); -} - -.window-tilepreview-swap { - border-width: 1px; - border-color: rgba(162, 247, 43, 0.4); - border-style: solid; - border-radius: 14px; - background-color: rgba(162, 247, 43, 0.4); -} - -.window-tilepreview-tabbed { - border-width: 1px; - border-color: rgba(98,160,234,0.3); - border-style: solid; - border-radius: 14px; - background-color: rgba(98,160,234,0.2); -} - -/* Keybindings Cheatsheet Overlay */ - -.forge-cheatsheet { - background-color: #2d2d2d; - border-radius: 16px; - padding: 24px 32px; - border: 1px solid #4d4d4d; - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); -} - -.forge-cheatsheet-title { - font-size: 16px; - font-weight: bold; - color: #ffffff; - margin-bottom: 20px; - text-align: center; -} - -.forge-cheatsheet-category { - font-size: 13px; - font-weight: bold; - color: #78aeed; - margin-top: 16px; - margin-bottom: 8px; -} - -.forge-cheatsheet-row { - font-size: 12px; - color: #eeeeec; - margin: 4px 0; - padding: 2px 0; -} - -.forge-cheatsheet-key { - font-family: monospace; - font-weight: bold; - color: #f5c211; - min-width: 180px; -} - -.forge-cheatsheet-desc { - color: #d0cfcc; -} \ No newline at end of file diff --git a/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md b/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md index fa88440..5c5cd55 100644 --- a/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md +++ b/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md @@ -280,6 +280,33 @@ The README's Desktops section is rewritten to describe one desktop. The comment depends on it, so a future reader does not mistake it for GNOME-session residue and remove it. `gnome-settings-hyprland.desktop` stays. +Searching for the rest of it found nothing else to cut, and that is worth +recording so nobody goes looking again. `change-settings` never enabled a GNOME +extension. The mentions of Dash-to-Dock, Openbar and Vitals scattered through the +shell are comments saying what a component was modelled on — `Dock.qml` explaining +which intellihide behaviour it reproduces, `Theme.qml` naming where a colour came +from — and `DESKTOP-PARITY.md` is the table of what replaced what. Those are +provenance, not residue: they are the reason the components behave the way they +do, and deleting them would cost the explanation while saving nothing. `Vitals` in +`config/dot/quickshell/services/` is Panama's own bar service and merely shares a +name with the extension it replaced. + +The panel list this spec gave for the handoff was already wrong when it was +written: it named Wacom, which nothing hands off to, and Region, which is a +subpage of System rather than a panel. The nine actual panels are colour, +keyboard, network, online-accounts, privacy, sound, system, universal-access and +wellbeing, and the allow-list in `services/SystemSettings.qml` is what decides. +The comment on `gnome-control-center` in `desktop-packages` repeated the wrong +list and has been corrected to match. + +One test gap turned up here and is closed. The assets contract caught a directory +under `config/dot/` that nothing links, but not the inverse — a name left in the +`dirs` array with no directory behind it, which makes `link-dotfiles` point +`~/.config/` at nothing. Deleting Forge was the exact move that introduces +it, and nothing would have failed if the array entry had been left behind. A +dangling symlink is worse than a missing one, because everything that looks there +finds something. + ### The `panama` command Three subcommands are added to the existing dispatcher, which was written to grow @@ -401,7 +428,11 @@ installer. They remain recoverable from sunhat's git history. They are clutter, not risk; pruning them stays in phase 6. - Guard the `.cargo/env` source in `config/bash/.bashrc` and remove the Codex block. - Rewrite the README: one desktop, the real install stages, and the test suite. -- Audit `docs/settings.md` (21K) for claims that no longer hold. +- **Done, and it needed nothing.** `docs/settings.md` is generated from + `PreferenceSchema.qml` by `panama-settings-docs`, and a contract already fails + when the copy is stale. It is current, all 133 settings, and carries no claim + about GNOME or Forge at all. The audit this line asked for was a manual reading + of a file that cannot go stale without a test saying so. ## Phases diff --git a/setup/packages/desktop-packages b/setup/packages/desktop-packages index ea6702b..92fdfe8 100644 --- a/setup/packages/desktop-packages +++ b/setup/packages/desktop-packages @@ -20,8 +20,10 @@ ghostty # The Calendar agenda opens events in this; see CalendarAgenda.qml. gnome-calendar # NOT GNOME-session residue. Panama's own Settings hands off to this for the -# panels it deliberately does not own -- Online Accounts, Region, Colour, -# Accessibility, Wellbeing, Wacom. See SystemSettings.qml's panel allow-list. +# panels it deliberately does not own -- Online Accounts, Color, Sound, Network, +# Keyboard, Privacy, Wellbeing, Accessibility, and the System panel for users, +# date and time, region and remote desktop. See the allow-list in +# services/SystemSettings.qml, which is what decides. gnome-control-center # install-hardware sets the nouveau blacklist and nvidia-drm.modeset with # grubby, which replaces an argument it already set rather than appending a diff --git a/setup/scripts/link-dotfiles b/setup/scripts/link-dotfiles index d403d47..1c0c844 100755 --- a/setup/scripts/link-dotfiles +++ b/setup/scripts/link-dotfiles @@ -30,10 +30,15 @@ log "Symlinking Panama .bashrc file to ~/.bashrc" ln -s "$PANAMA_BASH/.bashrc" "$HOME/.bashrc" # Each entry is symlinked as ~/.config/ -> $PANAMA_DOT/. -# "forge" is the GNOME tiling extension; "hypr"/"quickshell"/"wofi" are the -# Hyprland desktop. They coexist deliberately — the GNOME session keeps working -# while Hyprland is being used, so you can log back into either. -dirs=("espanso" "forge" "ghostty" "gtk-3.0" "gtk-4.0" "hypr" "kitty" "nvim" \ +# +# One desktop. "forge" was here while the GNOME session was still the fallback +# and Hyprland was being built beside it -- that hedge has been paid off, and a +# configuration for an extension nothing installs is worse than no configuration +# at all, because it reads as a supported thing. +# +# gnome-control-center is a separate matter and stays declared: Panama's own +# Settings hands off to it for the panels it deliberately does not own. +dirs=("espanso" "ghostty" "gtk-3.0" "gtk-4.0" "hypr" "kitty" "nvim" \ "quickshell" "tmux" "uwsm" "vicinae" "wofi" "xdg-desktop-portal") # --- Vim vimrc --- diff --git a/tests/quickshell/declared-assets-contract b/tests/quickshell/declared-assets-contract index f4856d2..f1dc0ba 100755 --- a/tests/quickshell/declared-assets-contract +++ b/tests/quickshell/declared-assets-contract @@ -187,6 +187,28 @@ for dot_dir in "$repo_dir"/config/dot/*/; do || note "config/dot/$name is referenced by neither link-dotfiles nor the shell configuration, so nothing puts it into service" done +# ── 6. Names in the array with nothing behind them ─────────────────────────── +# +# The inverse of the check above, and the one that bites when a directory is +# removed rather than added: an entry left in `dirs` makes link-dotfiles point +# ~/.config/ at a path that does not exist, and a dangling symlink is +# worse than no symlink, because everything that looks there finds something. +# +# Missed the first time this contract was written. Deleting config/dot/forge in +# the GNOME excision was caught by nothing until the array entry was removed too, +# which was luck rather than a test. + +mapfile -t linked_dirs < <(sed -n '/^dirs=(/,/)/p' "$repo_dir/setup/scripts/link-dotfiles" \ + | grep -oE '"[^"]+"' | tr -d '"') + +(( ${#linked_dirs[@]} > 0 )) \ + || note "link-dotfiles' dirs array could not be read, so nothing checked what it links" + +for name in "${linked_dirs[@]}"; do + [[ -d "$repo_dir/config/dot/$name" ]] \ + || note "link-dotfiles links $name, but config/dot/$name does not exist -- that is a dangling symlink in ~/.config" +done + # ── Report ─────────────────────────────────────────────────────────────────── # One asset named by three different files is one finding, not three.