panama-sudo is pkexec with a stated reason: the reason travels to the shell over the existing polkit IPC target, and the prompt renders it labeled "Stated reason (unverified)" beside polkitd's real action message -- beside, never instead of, because any process can claim any reason and the action text is the trust anchor. Reasons are single-shot and expire in ten seconds, so a stale one cannot dress up an unrelated prompt; without a reason, a running shell, or qs the wrapper is exactly pkexec. Built for agents, so the person typing their password learns what for. Verified live end to end -- reason shown, consumed once, expired when stale, cleared on dismissal -- and pinned by the polkit reason contract.
194 lines
9.6 KiB
Markdown
194 lines
9.6 KiB
Markdown
# Panama
|
|
|
|
Formerly Sunhat. A personal config for Fedora, with the intention of helping a
|
|
user set up their Fedora system with one command.
|
|
|
|
```sh
|
|
bash <(curl -fsSL https://git.gbrown.org/gib/Panama/raw/branch/main/boot)
|
|
```
|
|
|
|
`boot` installs git if the machine lacks it, clones this repository to
|
|
`~/.local/share/Panama` (or `$PANAMA_PATH`), and hands off to `install`. It is
|
|
deliberately small enough to read first, and the same two steps by hand work
|
|
identically:
|
|
|
|
```sh
|
|
git clone https://git.gbrown.org/gib/Panama.git ~/.local/share/Panama
|
|
~/.local/share/Panama/install
|
|
```
|
|
|
|
Both are safe to run again: an existing clone is fast-forwarded rather than
|
|
replaced, and `install` is the upgrade path.
|
|
|
|
`install` asks its questions first and then runs the stages in `setup/scripts/`
|
|
in order, without stopping again:
|
|
|
|
| Script | Does |
|
|
|---|---|
|
|
| `interview` | Every prompt, before anything is installed. Answers last one run and are never written to a durable path |
|
|
| `install-packages` | Repos (RPM Fusion, Terra, Hyprland COPR), the package lists in `setup/packages/`, then whichever optional categories were chosen |
|
|
| `link-dotfiles` | Symlinks `config/dot/<name>` → `~/.config/<name>`, and seeds the wallpaper, cursor theme and Firefox chrome |
|
|
| `change-settings` | Copies `config/copy/` over `/`, applies gsettings, enables user services |
|
|
| `link-vicinae-scripts` | Publishes the Vicinae script commands |
|
|
| `setup-identity` | git config, `gh auth login`, an SSH key — whichever were asked for |
|
|
| `install-hardware` | NVIDIA, Secure Boot enrollment, Fedora's extras, firmware — each only if it was asked for. Last, because enrollment and firmware are consumed at the next boot |
|
|
|
|
The run ends with a health summary from `panama-doctor`, which reports what is
|
|
actually running rather than what was attempted. It never fails the install: on a
|
|
fresh machine it legitimately reports things as not yet configured.
|
|
|
|
### Optional applications
|
|
|
|
Every machine gets the lists in `setup/packages/`. The interview also offers the
|
|
categories in `setup/packages/extras/` as a checklist, so a work laptop need not
|
|
acquire emulators and a desktop need not skip Steam. Nothing is preselected.
|
|
|
|
A category is one file. A bare line is a dnf package and a `flatpak:` line is a
|
|
Flathub ID, because the applications in a category do not all come from one
|
|
place. Adding a category is adding a file — the menu is read from the directory,
|
|
not written down anywhere.
|
|
|
|
Existing configs are moved to `config/old/` rather than overwritten.
|
|
|
|
## The desktop
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
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 |
|
|
|---|---|
|
|
| `config/dot/hypr/` | Compositor config. **Lua, not hyprlang** — see its README |
|
|
| `config/dot/quickshell/` | The shell: bar, dock, Continuum overview, Settings, Screen Intelligence, focus sessions, quick settings, notifications, screenshot UI |
|
|
| `config/containers/` | Container definitions systemd runs as units — currently the speech-to-text server behind dictation |
|
|
| `config/dot/vicinae/` | Raycast-style launcher, themed. Its commands live in `config/local/share/vicinae/` — script commands, and one compiled extension that adds web search with live suggestions |
|
|
| `config/dot/uwsm/` | Session environment (see the uwsm caveat in the hypr README) |
|
|
| `config/dot/wofi/` | Fallback launcher, in case the shell fails to start |
|
|
| `config/dot/xdg-desktop-portal/` | Portal backend routing |
|
|
|
|
**Start here: [`config/dot/hypr/README.md`](config/dot/hypr/README.md)** — it
|
|
covers the Lua migration, the uwsm environment gotcha, the HDR decision, the
|
|
full keymap, and troubleshooting.
|
|
|
|
Log in as **"Hyprland (uwsm-managed)"**, not plain "Hyprland".
|
|
|
|
## Layout
|
|
|
|
```
|
|
bin/ Small user-facing commands on PATH; `panama` is the entry point
|
|
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
|
|
containers/ Quadlets, linked into ~/.config/containers/systemd
|
|
local/ Icons, the cursor theme, and the launcher's commands and
|
|
extensions, linked into ~/.local/share
|
|
old/ Backups of whatever was replaced (gitignored)
|
|
wallpapers/ Copied into ~/Pictures/Wallpapers when absent
|
|
setup/
|
|
apps/ Applications built from source, one file each
|
|
lib/ Shared by more than one stage; the extras catalog reader
|
|
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
|
|
|
|
133 of them, under `tests/`. Run the lot, or a subset by pattern:
|
|
|
|
```sh
|
|
panama test # everything
|
|
panama test dock # just the ones matching "dock"
|
|
tests/setup/interview-contract # or one directly; they are plain executables
|
|
```
|
|
|
|
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
|
|
```
|
|
|
|
## Projects
|
|
|
|
A project is the set of windows you open together — which applications, which
|
|
workspace each was on, and for a terminal, which directory it was sitting in.
|
|
Arrange the desktop, then run **Save Layout as Project** from the launcher and
|
|
name it; **Open Project** lays it out again.
|
|
|
|
Workspaces are recorded as positions rather than numbers, and opening a project
|
|
claims free ones, so it never lands on top of what you are already doing. An
|
|
application that refuses to open twice — Slack, Thunderbird, the browser — is
|
|
moved into place rather than launched again. Saved layouts are listed on the
|
|
Desktop settings page, which is also where they are removed.
|
|
|
|
## The `panama` command
|
|
|
|
```sh
|
|
panama update # review, commit and sync this repo
|
|
panama edit # open it in Neovim
|
|
panama doctor # what is actually running, not what was installed
|
|
panama test # every contract, or a subset by pattern
|
|
panama upgrade # re-run ./install from anywhere
|
|
panama apps # choose applications to install, by category
|
|
panama app # applications no repository carries; build one by name
|
|
```
|
|
|
|
`panama apps` is the optional-application catalog, opened after the fact. The
|
|
interview offers the same categories during `./install`, whole; this picks a
|
|
category and then the applications inside it, so a machine can acquire Slack in
|
|
March without having wanted Discord in January. Both read
|
|
`setup/lib/extras-catalog`, so the two cannot describe different catalogues.
|
|
|
|
A category is one file under `setup/packages/extras/`. A bare line is a dnf
|
|
package, a `flatpak:` line is a Flathub id, `| Name` gives the menu something
|
|
readable, and an indented line belongs to the entry above it — which is how OBS
|
|
carries its sixteen plugin extensions as one thing to tick.
|
|
|
|
`panama-sudo` is pkexec with a stated reason: `panama-sudo --reason "why" --
|
|
command` shows the reason on Panama's password prompt, clearly labeled as an
|
|
unverified claim beside polkitd's own action text — meant for agents and
|
|
scripts, so the person typing the password learns why before they do. Without
|
|
a reason, a running shell, or `qs` it behaves exactly like pkexec.
|
|
|
|
`panama app` is deliberately not part of `./install`. Everything else Panama
|
|
installs comes from dnf or Flathub; these are built from source because no
|
|
packaged form exists, and a source build is slow, wants the network throughout,
|
|
and depends on an upstream that moves. That is the failure the interview exists
|
|
to prevent, so asking for one is something you do on purpose — and it is also
|
|
how you rebuild when a new version ships. Nothing is pinned: each build takes
|
|
the current upstream and reports a failure rather than working around it.
|
|
|
|
Adding one is adding a file to `setup/apps/`, and the file has to say why the
|
|
exception exists.
|
|
|
|
None of the scripts in this repository carry a `.sh` extension. A shebang and
|
|
the executable bit already select the interpreter, and the extension only
|
|
becomes something to keep in sync — which it did not stay.
|