chore: sync master into dev + harden macOS bootstrap binary path (Codex P1) - #39
Merged
Conversation
…d app_id Prepares the systemd unit and the egui GUI for the deb/rpm/pacman packages. - splitway.service: ExecStart now passes `--config /var/lib/splitway/config.json` and the unit declares StateDirectory=splitway (0700), mirroring nix/module.nix. The daemon creates its config under the persistent, daemon-owned state dir on first run instead of falling back to /root/.config (and logging a warning). - Add the same --config to the commented socket-group opt-in ExecStart override. The bare `ExecStart=` reset fully replaces the command, so without this an opt-in user would silently drop --config and reintroduce the /root/.config fallback this commit removes. (Minor deviation from the "keep the block untouched" plan, for correctness/consistency with the main ExecStart and nix/module.nix.) - splitway-gui: set the ViewportBuilder app_id to io.github.stslex.splitway so Wayland compositors map the window to the packaged .desktop entry + hicolor icon (shipped under that basename by the GUI package). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Adds the MIT LICENSE (the repo had none) and declares `license = "MIT"` on every workspace crate, then defines the deb + rpm metadata for the core `splitway` package on splitway-daemon. The package ships both binaries — `splitway-daemon` and the `splitway` CLI (from splitway-cli) — plus the systemd unit and README/LICENSE. It is built musl-static (*-unknown-linux-musl) so it has no shared-library dependencies and installs on any glibc/musl baseline; the desktop GUI is a separate package (next commit) that Depends on this one. - [package.metadata.deb]: name=splitway, binaries to /usr/bin, copyright from the MIT text, Recommends network-manager + systemd-resolved (not Depends), empty Depends (static). An (empty) maintainer-scripts dir enables cargo-deb's systemd-units integration to generate the postinst/postrm: enable+start on install, restart on upgrade, stop on remove, daemon-reload. - [package.metadata.generate-rpm]: same layout, auto-req disabled (static), weak-dep Recommends, raw /bin/sh systemd scriptlets (cargo-generate-rpm does not expand %systemd_* macros). Asset-path note (verified by building both packages with cargo-deb 3.7.0 and cargo-generate-rpm 0.21.0): cargo-deb resolves non-`target/` asset paths relative to THIS crate's manifest dir (so workspace-root files use `../`), while cargo-generate-rpm resolves relative to the invocation dir (workspace root, bare paths) — hence the intentional path skew between the two blocks. Version is stamped at the packaging layer (cargo deb --deb-version / cargo generate-rpm --set-metadata) so dev builds get <ver>~dev.<utc>.<sha> without a non-semver string in Cargo.toml. CI builds per-triple with --target (remaps target/release -> target/<triple>/release and stamps the arch). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
…opt-in A separate `splitway-gui` package for the egui desktop GUI (glibc, dynamic), which Depends on the musl-static core `splitway` (>=, the IPC compat contract). - .desktop (io.github.stslex.splitway.desktop, Exec=splitway-gui) + hicolor icons rasterized from assets/icon/splitway-icon.svg (8 PNG sizes + scalable SVG, basename = app_id) via packaging/icons/generate-hicolor.sh. The icon tree is committed so every packaging path ships it without a rasterizer; the .desktop passes desktop-file-validate. - Dependencies (both formats, verified by building real packages): the eframe/glow windowing libs are DLOPEN'd by winit/glow at runtime, so they are absent from the ELF DT_NEEDED and neither cargo-deb's $auto nor cargo-generate-rpm's auto-req can detect them — they MUST be hardcoded. deb: libgl1, libx11-6, libxcursor1, libxi6, libxrandr2, libwayland-client0, libxkbcommon0, libc6 (>= 2.31 floor). rpm: mesa-libGL, libX11, libXcursor, libXi, libXrandr, libwayland-client, libxkbcommon (auto-req still pins the glibc floor from libc/libgcc sonames). Recommends an XDG desktop portal + backend for rfd's file dialog. - Socket-group opt-in (security-sensitive): the maintainer scripts create an EMPTY `splitway` group and install a service drop-in switching the daemon to group-socket mode (0660 root:splitway, dir 0750). EMPTY-GROUP INVARIANT: with no members the posture is identical to the default 0600 root-only; the scripts NEVER add a user — the only grant is a human running `usermod -aG splitway <user>` + re-login. postinst installs the drop-in + reloads + restarts; postrm removes it, groupdel only if empty, reverting to root-only. A loud first-install message prints the exact opt-in one-liner. Validated by building both packages with cargo-deb 3.7.0 / cargo-generate-rpm 0.21.0 and inspecting deps, files, and scriptlets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
…tests New packaging.yml (no secrets — gates the PR). The publish/sign job is added in the next commit. - meta: compute the channel version once (compute-version.sh). Release (push to master) = clean <X.Y.Z>; dev/PR/dispatch = <X.Y.Z>~dev.<utc>.<sha>, which sorts below the release in dpkg and rpm. - build-core (amd64 + arm64): `cross` builds splitway-daemon + splitway CLI musl-static, asserts `file` reports "statically linked", then cargo-deb / cargo-generate-rpm with --target (remaps target/release + sets arch) and the stamped version. Emits deb + rpm + tarball. - build-gui (amd64 + arm64): builds the egui binary INSIDE debian:bullseye (glibc 2.31 floor, so the libc6 (>= 2.31) / rpm GLIBC requires are true), arm64 on a native arm64 runner (no QEMU). Rewrites the core-dependency floor to the built version for dev channels, then packages on the host. - test-install (debian:bookworm, ubuntu:22.04, fedora:latest): installs the built artifacts directly; asserts the binaries run, the unit validates (systemd-analyze verify), the GUI pulls splitway + the GL deps, the empty `splitway` group exists with no members, and the .desktop validates. - test-signed-repo: generates a THROWAWAY gpg key, builds + signs local apt (build-apt-repo.sh) and dnf (build-dnf-repo.sh) repos from the artifacts, serves them over localhost, and installs with signature verification ON — proving metadata + signing + verify end-to-end with no production secret. (Those two repo scripts are reused by the real publish job next commit.) - test-arm64-smoke: best-effort arm64 deb install under QEMU. Validated locally: actionlint clean (incl. shellcheck of run blocks); all helper scripts shellcheck-clean; the deb/rpm builds + --target/--deb-version/ --set-metadata flags exercised against cargo-deb 3.7.0 / cargo-generate-rpm 0.21.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Adds the publish-pages job (secrets) and the signing plumbing reused by the
PR-time ephemeral-key test.
- publish-pages: runs on push to master (release) / dev (dev) and dispatch,
NEVER on pull_request, gated behind the build + test jobs. Serialized by a
single `pages-deploy` concurrency group (cancel-in-progress: false) so two
deploys queue rather than clobber. Imports the RSA signing key, checks out
(or bootstraps) the persistent gh-pages branch, drops the artifacts into the
correct channel pool, regenerates + signs ONLY that channel's apt + dnf
metadata, publishes the armored pubkey to splitway.gpg, renders index.html,
and commits + pushes — MERGE, never wipe, so old versions and the other
channel survive. Release additionally attaches the tarballs to the v<ver>
GitHub Release. A post-deploy smoke waits for Pages to go live, then installs
from the real repo with signature verification ON (apt + dnf).
- build-apt-repo.sh / build-dnf-repo.sh: optional SPLITWAY_GPG_PASSFILE feeds
the real key's passphrase via loopback (never on a command line); unset for
the passphrase-less ephemeral key.
- render-index.sh: the Pages landing page with per-distro, per-channel
add-repo snippets + the key fingerprint.
- RSA fix: the throwaway test key (and, by requirement, GPG_PRIVATE_KEY) is RSA
— rpm --addsign only produces a verifiable signature with RSA; an EdDSA key
silently yields no RPMTAG_RSAHEADER (found + fixed via local signing tests).
Validated locally: apt InRelease + Release.gpg verify Good; per-arch Packages
filtering correct; dnf repomd.xml.asc verifies; RSA-signed rpm passes rpm -K
("digests signatures OK"). actionlint + shellcheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Closes Arch via a self-hosted, GPG-signed pacman repo (reusing the apt/dnf key + Pages), since AUR registration is disabled. x86_64 for the hosted repo; aarch64 users use the in-repo splitway-bin PKGBUILD. PKGBUILDs in packaging/aur/ (also usable now via `makepkg -si`): - splitway: source build of daemon + CLI from the release tag; makedepends cargo; ships both binaries + unit; splitway.install prints the enable hint (Arch policy: no auto-enable); optdepends networkmanager / systemd-resolvconf. - splitway-bin: prebuilt from the release tarball (x86_64 + aarch64); provides/conflicts splitway. - splitway-gui: source egui GUI; depends splitway + libglvnd/libxkbcommon/ wayland/libx11/libxcursor/libxi/libxrandr; optdepends xdg-desktop-portal; splitway-gui.install mirrors the deb/rpm empty-group + drop-in invariant. CI (packaging.yml): - build-arch: archlinux container, non-root makepkg of the two source PKGBUILDs from THIS checkout (clean version — pacman has no ~dev channel because vercmp does not treat ~ as a pre-release marker), validates .SRCINFO + namcap (advisory). x86_64 .pkg.tar.zst artifacts. - test-arch: pacman -U local install (asserts binaries + unit + empty group), then a throwaway-RSA-key signed repo — repo-add --sign, pacman-key --add/--lsign, SigLevel = Required DatabaseOptional, pacman -Sy with verification ON. - publish-pages (release only): copies the .pkg.tar.zst into the persistent arch/release/x86_64 subtree, detach-signs each with the real key, repo-add (in a container) incrementally (old packages preserved), replaces Pages- hostile db/files symlinks with real signed copies, reuses splitway.gpg. Post-deploy: live `pacman -Sy splitway` with verification ON. - render-index.sh: Arch section (signed repo primary, makepkg alternative, AUR pending). DEFERRED (not here): the automated AUR ssh push — blocked on AUR registration reopening. The in-repo PKGBUILDs are the bridge. Validated locally: all PKGBUILD/.install bash-syntax-clean; actionlint clean; index renders with $arch left literal for pacman. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Docs only — no code. - README: Install sections for apt / dnf (both channels) and Arch (signed pacman repo primary, in-repo PKGBUILD makepkg alternative; AUR pending), with the key-verification note. NixOS section left as-is. - packaging/README.md: a Distribution packages (deb / rpm / pacman) section — the two-package split, dev vs release channels + ~dev versioning, the glibc 2.31 floor, the dlopen'd GL deps, the GUI socket-group drop-in + empty-group invariant, and the pacman specifics (x86_64-only, no ~dev channel, detached signing, repo-add incrementality). - docs/design/linux-distro-packaging.md: the durable record — decisions 1-7, the channel/version topology, dep lists, signing + merge mechanics across all three formats (incl. the RSA-not-EdDSA and cargo-deb-vs-generate-rpm path-resolution gotchas), the two-layer test design, the pacman-now/AUR-later Arch strategy, and the signing key. - ROADMAP.md: Phase 6 marked done (Linux), noting the two-package design supersedes the original one-package sketch; macOS Homebrew + the automated AUR push remain deferred. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
No behavior change for the current (validated) inputs — robustness only, flagged by an adversarial self-review of the diff: - build-apt-repo.sh: `break` after the first Architecture line in the per-arch Packages filter (the canonical value; a valid stanza has exactly one). - packaging.yml: `g` flag on the GUI core-dep-floor seds (defensive if more `splitway (>=` references are ever added). - packaging.yml: comment that test-arm64-smoke is intentionally not a publish gate (best-effort under QEMU, continue-on-error). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Resolves the Codex + self-review findings on the Phase 6 packaging PR. Build-blocking CI fixes: - static-linkage gate: assert no dynamic interpreter instead of requiring the literal "statically linked" (musl x86_64 is "static-pie linked") — unblocks build-core (amd64) and the whole deb/rpm pipeline - test-arch: read the GPG fingerprint from fpr field 10, not 5 (5 is empty) - AUR splitway-bin: rename splitway.install -> splitway-bin.install so install="$pkgname.install" resolves (makepkg no longer aborts) - build-gui: CARGO_NET_RETRY + a retrying `cargo fetch --locked` before the offline build, hardening the transient arm64 crates.io failure Supply-chain / correctness: - apt: dearmor the published (armored) key into the binary keyring at every consumption site (works on every apt version; the published file stays armored for rpm --import / pacman-key) - publish: fail-closed signature verification (apt InRelease+Release.gpg, dnf repomd + per-rpm RSA header, pacman db+pkg sigs) BEFORE the gh-pages push - apt Release: Valid-Until (APT_VALID_DAYS, default 90d; LC_ALL=C) for freeze/replay protection - dev-floor sed: anchor to the dependency lines (leave the comment), and assert the floor was actually stamped - signed-repo tests (apt/dnf/pacman) now install splitway-gui too, exercising the GUI package under signature enforcement Arch / consistency / docs: - splitway-gui PKGBUILD: splitway>=$pkgver floor + hicolor-icon-theme, desktop-file-utils - new check-pkgver-sync.sh (meta job): daemon version == every PKGBUILD pkgver - render-index/README: dearmor --yes for apt, pacman-key --init, dev-channel keyring install - splitway-bin SKIP digest documented + tracked for the deferred AUR-push phase Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oling Follow-up to the second Codex pass on PR #36. - splitway-bin: `provides=("splitway=$pkgver")` (was unversioned). pacman only satisfies a versioned dependency from a versioned provision, so splitway-gui's new `splitway>=$pkgver` floor could not install against the prebuilt core. - test-signed-repo: install `rpm` in the tooling step. build-dnf-repo.sh needs `rpm --addsign`; it passes today only because ubuntu-latest pre-installs rpm — make it explicit (matches the publish job) so the dnf signing path is robust. - packaging/README.md: document the one-time config relocation for users who ran the daemon by hand as root before packaging (old XDG fallback /root/.config/splitway -> /var/lib/splitway). No maintainer-script migration: no published package used the old path, it is config-not-read (not data loss), and the deb core postinst is cargo-deb-generated (#DEBHELPER#) from an empty dir, so a hand-written migration would risk breaking systemd enablement that the docker install-test (no systemd) could not catch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `meta` gate (check-pkgver-sync.sh) requires every packaging/aur/*/PKGBUILD `pkgver=` to equal the daemon version, but release.yml's bump-version job only bumped splitway-daemon/Cargo.toml. So the first post-release auto-bump would leave the three PKGBUILDs behind and fail every later packaging run in `meta` until a human hand-edited all three. - Add packaging/ci/sync-pkgver.sh: the write side of the lockstep invariant (symmetric with check-pkgver-sync.sh, same daemon-version read). It stamps the daemon version into each PKGBUILD `pkgver=` and resets `pkgrel=1` (Arch convention on a version change). The `$pkgver`-derived fields (source URLs, provides, depends floor) follow automatically. - release.yml bump-version: run sync-pkgver.sh after the Cargo.toml bump and `git add` the PKGBUILDs into the same commit. Verified locally: no-op when already in sync (no diff), correct bump on a simulated 0.0.5 -> 0.0.6, and check-pkgver-sync.sh passes against the result. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…review) Two findings from Codex's re-review of b326036: - P2 (splitway-gui/Cargo.toml): the deb declared libgl1 but not libegl1, and the rpm required mesa-libGL but not mesa-libEGL. glow/glutin creates its GL context via EGL on Wayland (glutin_egl_sys is in Cargo.lock; GLX on X11), and libgl1 does NOT pull libegl1 — so a minimal Wayland-only install would succeed and then fail at GL-context creation. Add libegl1 (deb) and mesa-libEGL (rpm); both pull the libglvnd EGL loader, mirroring how libgl1/mesa-libGL pull GLX. Arch is unaffected (libglvnd already provides libGL + libEGL). Doc + comments updated. - P1 (packaging.yml test-arch): the local `pacman -U` smoke preinstalled the GL/X11/wayland libs but not hicolor-icon-theme/desktop-file-utils, which the splitway-gui PKGBUILD declares as hard deps. `pacman -U` on local files only auto-resolves deps from a synced repo DB, so the smoke must not lean on that — preinstall the full declared set explicitly, matching the PKGBUILD. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iew round 3) Codex re-review (1) + self-review (4) of 6de36d7: - P2 (Codex, splitway-gui): add the X11 xkb runtime lib. winit's default `x11` feature has xkbcommon-dl dlopen libxkbcommon-x11.so (confirmed in Cargo.lock), a SEPARATE package from libxkbcommon on Debian (libxkbcommon-x11-0), Fedora (libxkbcommon-x11) AND Arch (libxkbcommon-x11 — verified via the Arch package API: it provides libxkbcommon-x11.so and is NOT bundled in the base libxkbcommon). Without it an X11 session can fail to load the lib before the window opens. Added to the deb Depends, rpm Requires, the Arch GUI PKGBUILD depends, and both Arch CI preinstall lists. - P2 (postinst): the groupadd under `set -e` was the only unguarded mutating step. Keep the abort (the drop-in is meaningless without the group) but make it deliberate + diagnosable with an explicit error message + exit. - P2 latent (version reads): `grep '^version' … | head -1` SIGPIPEs grep under `set -o pipefail` if a second match ever appears. Replaced with a SIGPIPE-free `awk -F'"' '/^version/{print $2; exit}'` in compute-version.sh, check-pkgver-sync.sh (+ the pkgver read), sync-pkgver.sh and release.yml (x3). - P2 (splitway-bin): surface the same networkmanager / systemd-resolvconf optdepends as the source splitway PKGBUILD (identical daemon, same prereqs). - P2 (README niri): the interim egui GUI now sets `.with_app_id(...)` and the packaged splitway-gui ships the matching .desktop + icons, so the app-id window rule is no longer Tauri-only; clarified the packaged GUI is the egui build. Also quoted "$GITHUB_OUTPUT" in the release.yml blocks touched above (pre-existing SC2086). actionlint + shellcheck clean; awk reads verified to yield 0.0.5 and check-pkgver-sync passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…emon (Codex P2) The post-release auto-bump stamped the AUR PKGBUILDs with the *next* (unreleased) daemon version, so `makepkg -si` from master pointed at a `v$pkgver` tag / release assets that do not exist yet. - release.yml: run sync-pkgver.sh BEFORE the daemon bump so the PKGBUILDs pin the just-released version; bump the daemon afterwards for the next cycle. - check-pkgver-sync.sh: validate the pinned pkgver names a release tag that EXISTS (all three PKGBUILDs agreeing), with a no-tags bootstrap fallback — instead of requiring equality with the in-tree daemon version. - packaging.yml: fetch-depth: 0 on the meta checkout so the gate sees tags. - docs/design: record the invariant and why the gate checks existence, not "latest" (avoids spurious dev/PR and release-window failures). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
… daemon (Codex P2) Follow-up to pinning the AUR pkgver to the released tag: the daemon version now intentionally runs ahead of the committed pkgver. build-arch pre-placed the checkout tarball as <pkg>-$VERSION.tar.gz (daemon version), but the PKGBUILD's source= expects <pkg>-$pkgver.tar.gz. When the two diverge makepkg can't find the local archive and silently downloads the old v$pkgver tag, building stale code while the smoke test still passes. Read pkgver from each PKGBUILD and key both the archive filename and the git-archive --prefix on it, so the pre-placed checkout is always the source makepkg uses. Drop the now-unused VERSION env. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
…inned tag (Codex P1) The committed PKGBUILD pkgver intentionally lags to the last released tag (so a user's `makepkg -si` resolves an existing tag), but the hosted pacman repo must ship the version being released. The prior approach keyed the build on the committed pkgver, so a release push would publish Arch packages under the PREVIOUS version and Arch users would never receive the new one. build-arch now stamps the daemon/meta version into the EPHEMERAL PKGBUILD (never committed) and pre-places the matching <pkgname>-<VERSION>.tar.gz so makepkg builds THIS checkout as VERSION — no tag download, correct published version. The committed PKGBUILDs and the check-pkgver-sync.sh gate are untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
`pacman -Sy <pkg>` refreshes the sync databases without upgrading, leaving the DB ahead of installed packages and resolving deps from a partial-upgrade state. Use `-Syu` in the hosted-index and README install snippets. The CI smoke tests keep `-Sy` (throwaway containers, not user systems). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
Phase 6: Linux distribution packaging (apt / dnf / pacman + signed GitHub Pages repos)
origin/master carried splitway-daemon Cargo.toml=0.0.6 with a stale Cargo.lock=0.0.5: release.yml's post-release auto-bump rewrote the toml but never relocked. The dev->master merge tree inherited that drift, so `cargo fetch --locked` (build-arch's makepkg prepare) and `cargo build --frozen` (build-gui) aborted with "cannot update the lock file ... because --locked was passed" — the red build-arch / build-gui checks on PR #37. - Sync this branch's Cargo.lock to daemon 0.0.6 (merged from master), so the merge tree is internally consistent and the packaging jobs build. - release.yml bump-version: add a toolchain, then `cargo update -p splitway-daemon --precise "$NEW_VERSION"` and stage Cargo.lock in the bump commit, so master never drifts again. - The bot bump commit gets `[skip ci]`: a GITHUB_TOKEN push already does not re-trigger workflows, but the marker makes it explicit (and holds if the push ever moves to a PAT), so the next-cycle bump can never publish an unreleased X.Y.(Z+1) to the stable channels (Codex P1). - ci.yml: a `cargo metadata --locked` guard fails loudly on any future Cargo.lock drift instead of letting it surface as a packaging abort. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The post-deploy steps poll the live Pages URL for 10 min and `exit 1` on timeout. On the first (root-commit) gh-pages deploy — Pages not yet enabled/propagated — the package is never served in the window, so the whole publish-pages job is reported failed even though the signed deploy already pushed and verified cleanly. Downgrade both liveness timeouts (apt/dnf smoke and the pacman smoke) to `::warning` + `exit 0`, skipping the live install. The pre-push "Verify all signatures (fail closed)" step still gates integrity before the push, and the actual install stays fatal once the repo IS live — only the propagation-timeout path is now non-fatal, so a verified publish is never reported as failed. Note: enabling GitHub Pages for the gh-pages branch is a one-time repo setting (Settings -> Pages -> Branch: gh-pages); nothing in CI can do it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
build-dnf-repo.sh: the single PASS_OPT string relied on word-splitting (SC2086 disabled) at the gpg call. Split it: pass_opt[] (array) for the direct gpg detach-sign — space-robust, mirroring build-apt-repo.sh's gpg_sign — and pass_macro (plain string, byte-identical to the original) for the rpm __gpg_sign_cmd macro, which rpm tokenizes itself and cannot take a bash array. The passphrase FILE path is mktemp-derived and never has spaces, so the macro keeps the proven form (zero regression on the real-key publish path, which has never run in CI). compute-version.sh: append GITHUB_RUN_NUMBER to the dev pkgver -> `<ver>~dev.<utc>.<run>.<sha>`. Two pushes in the same UTC second now order monotonically (run number is compared numerically) instead of falling back to the non-monotonic lexical short-sha compare. Defaults to 0 outside Actions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The design doc's GUI dependency lists had drifted from the manifests: - Debian: add libegl1 + libxkbcommon-x11-0 - Fedora: add mesa-libEGL + libxkbcommon-x11 - Arch: add libxkbcommon-x11 …with a note on why EGL is separate from GL (EGL context on Wayland) and xkbcommon-x11 separate from xkbcommon (winit x11 dlopen), and that the list is the windowing-lib subset (the PKGBUILD also carries the icon / desktop-file install-hook deps). Also update the now-stale dev version format `<X.Y.Z>~dev.<utc>.<sha>` -> `<X.Y.Z>~dev.<utc>.<run>.<sha>` in the channel-topology table and in packaging/README.md to match compute-version.sh. splitway-gui/Cargo.toml: document the rpm Recommends asymmetry — the deb offers gtk|wlr|kde but a cargo-generate-rpm `key="*"` table has no boolean-OR, so it names the GTK portal (a weak dep that works on most desktops); a passthrough rich-dep is left out until verified to emit correctly through cargo-generate-rpm. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The post-release auto-bump only updates master, so after each release dev falls one version behind (exactly the drift that left this branch at 0.0.5 while master was at 0.0.6). Add a `sync-dev` job (`needs: bump-version`) that opens — or refreshes — a PR merging master back into dev so dev tracks the next dev cycle automatically. A PR, not a direct push: dev follows the branch→PR workflow and may be protected. The job no-ops when dev already contains master, reuses an open sync PR instead of duplicating, and enables auto-merge best-effort (lands once mergeable where the repo allows it, otherwise waits for a one-click merge). The PR is opened by GITHUB_TOKEN, which does not trigger pull_request CI on itself — documented inline, with the PAT escape hatch for anyone who wants required checks to gate the sync merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The new `Verify Cargo.lock` step resolves against the crates.io index on a cold runner, so a transient blip (observed: `OpenSSL ... unexpected eof` fetching the tauri-codegen index entry) could flake it — unlike the rest of this repo's network steps, which already retry. Wrap it to match that pattern: CARGO_NET_RETRY=10 plus an outer retry that rides out a transient registry error, while still failing FAST on a real drift (the `--locked` refusal, which no retry can fix) with a clear relock hint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The source PKGBUILDs fetch the `v$pkgver` tag archive (generated the instant the tag exists), but splitway-bin fetches the release ASSET tarballs (splitway-$pkgver-linux-*.tar.gz) that packaging.yml attaches later and independently of release.yml's bump. So stamping splitway-bin at tag time could point it at not-yet (or, on a failed upload, never-) uploaded assets while check-pkgver-sync.sh still passes on tag existence alone (Codex P2). - sync-pkgver.sh: skip splitway-bin — only advance the tag-archive source PKGBUILDs at release time. - check-pkgver-sync.sh: exclude splitway-bin from the shared-version / tag check; it is allowed to lag, and tag-existence is necessary-but-not- sufficient for an asset-based fetch. splitway-bin's pkgver + real sha256sums are both knowable only after the assets are published, so they are owned together by the deferred asset-aware AUR-push automation (already referenced in its PKGBUILD's TRUST ASSUMPTION note). splitway-bin is not on AUR yet, so there is no live 404 surface today. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…odex P2) The GUI dlopens libwayland-egl.so.1 (glutin's Wayland EGL platform binds the GL surface to the wl_surface via wl_egl_window_*), but the manifest declared only libwayland-client0 / libwayland-client — and the client lib does NOT pull the EGL platform lib. So on a minimal Wayland host the package installs and passes the `command -v` smoke tests, then fails at GL-context creation. Verified the binary dlopens it: `strings splitway-gui | grep libwayland-egl` -> "Library libwayland-egl.so could not be loaded." + libwayland-egl.so.1. - deb depends: add libwayland-egl1 - rpm requires: add libwayland-egl - Arch is already covered: the `wayland` package ships libwayland-egl.so.1 alongside libwayland-client. - Manifest comments + docs/design dep lists updated with the rationale (separate from libwayland-client0, same pattern as libegl1 vs libgl1). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…p (Codex P2) The GUI maintainer scripts run groupadd/groupdel to create and remove the opt-in `splitway` socket group, but neither package declared the provider: groupadd is in `shadow-utils` (Fedora/RHEL) and `passwd` (Debian). On a minimal image lacking it: - rpm: %post fails NON-fatally, so the install "succeeds" but leaves the socket-group drop-in with no group — the daemon then exits on `--socket-group splitway` and users can't opt in (Codex P2). - deb: the postinst `exit 1`s, so the install fails loudly instead. Declare the dep on both for parity (present on normal systems, but now guaranteed on minimal ones): - rpm `[requires]`: add `shadow-utils` - deb `depends`: add `passwd` Manifest comments + the design-doc socket-group note updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # Cargo.lock # packaging/aur/splitway-gui/PKGBUILD # packaging/aur/splitway/PKGBUILD # splitway-daemon/Cargo.toml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two things, both needed before the
dev → masterrelease (#38) can land:1. Sync
master→dev(post-release version bump)mastercarried the post-release bump (469d01e) not ondev. Resolved the four version-line conflicts by taking master's values (this is the sync's whole point); after resolution those files are byte-identical to master:splitway-daemon/Cargo.toml+Cargo.lockpackaging/aur/splitway/PKGBUILDpkgverpackaging/aur/splitway-gui/PKGBUILDpkgverOnce this merges into
dev, thedev → masterPR #38 stops conflicting (verified:master ← (dev + this)is a clean tree).2. Harden the macOS bootstrap binary path (Codex P1 on #38)
The macOS self-installer pinned
/usr/local/bintoroot:wheel 0755before installingsplitway-daemon(run as root by launchd) — but renaming/replacing a directory entry needs write access to its parent, so on the Homebrew-on-Intel layout (admin-owned/usr/local) a non-root user couldmv /usr/local/bin /usr/local/bin.bak && mkdir /usr/local/bin, drop in a malicious daemon, and gain root at next boot. Pinning only the leaf dir didn't close it.scripts/bootstrap.shnow walks every ancestor up to/and refuses unless each is root-owned and not group/other-writable — run before the chown so the refusal path never re-chowns a pre-existing dir (keeps the never-half-configured contract). Parents are verified, never chowned (chowning/usr/localwould break a real Homebrew). Clean macOS / Apple-Silicon Homebrew (/opt/homebrew) are unaffected. Design doc updated.Verification
cargo fmt --all -- --check✓ ·cargo build✓ ·cargo clippy --all-targets -- -D warnings✓ ·cargo test✓ (43 passed)bash -n scripts/bootstrap.sh✓; parent-chain walk unit-tested (clean macOS → install proceeds; admin-owned or group-writable ancestor → refuse)🤖 Generated with Claude Code