worktree-console-plugin-update-all
3100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
141c04cd6b |
feat(web-console): "Update all" on the plugins screen
The Installed tab could only update one plugin at a time, one dialog and one watched job each. This adds the bulk action beside the list it acts on — the same place Sources keeps "Refresh all" — plus a count badge on the Installed tab trigger, because Browse is the tab the page opens on and a control nobody passes is a control nobody finds. The host takes ONE package operation at a time (409 otherwise: bun operations share a lockfile and a node_modules tree), so this is a queue the console works through job by job, driven by each job settling rather than by a timer. The run carries its own copy of what is left: every finished install invalidates the installed list, and a queue that re-derived itself would change shape underneath a run the operator already confirmed. Trust rules are unchanged, only taken once instead of N times. If any entry in the run comes from an operator-added source the whole dialog wears the external treatment and names those catalogs — a bulk action must not be a way to wave through, in one click, a warning each package would have shown on its own. The dialog lists every version change rather than a count, and names what it will not attempt: an update with no catalog entry, or one this host would refuse (400 on incompatible, blocked entries) never enters the queue, so the button's count still adds up on screen. A failure ends the run. The failed job's card is the only record of what went wrong, and starting the next install would replace it with a fresh spinner; the toast says what was applied and what was not, and the rows are still there to retry from. Also fixed, because this change leans on it: disabled buttons were invisible. AnimatedButton is a motion element and its mount animation settles as an inline `opacity: 1`, which outranks the `disabled:opacity-50` class the library also ships — measured `opacity: 1` on a disabled button, console-wide. Only `pointer-events: none` landed, so every disabled control in the app looked live and silently ignored the click. Corrected in the components/ui wrapper layer like the other @unom/ui adaptations. Verified: tsc, biome, `bun test server/`, production build, i18n check (650 messages, en + de). Storybook stories added for the list header and the confirm dialog; both rendered headless in light and dark, with the disabled states asserted on the DOM rather than by eye. |
||
|
|
155cced56b |
Merge pull request 'fix(flatpak): pin the skia-binaries archive to 0.99.0 — #193 bumped the crate and left the tarball at 0.87' (#196) from worktree-flatpak-skia-099-pin into main
android / android (push) Canceled after 9m25s
ci / rust (push) Canceled after 7m50s
ci / rust-arm64 (push) Canceled after 4m48s
ci / web (push) Canceled after 1m31s
ci / docs-site (push) Canceled after 32s
ci / bun-nix (push) Canceled after 0s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Canceled after 0s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Canceled after 0s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Canceled after 0s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Canceled after 0s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Canceled after 0s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Canceled after 0s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Canceled after 0s
docker / builders-arm64cross (push) Canceled after 0s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Canceled after 0s
docker / deploy-docs (push) Canceled after 0s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 0s
arch / build-publish (push) Successful in 11m33s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m2s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 18m30s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 6m56s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 21m27s
flatpak / build-publish (push) Successful in 25m44s
deb / build-publish (push) Successful in 4m8s
deb / build-publish-client-arm64 (push) Successful in 3m10s
deb / build-publish-gamescope (push) Successful in 55s
deb / build-publish-host (push) Successful in 5m53s
deb / smoke-install (push) Successful in 3m53s
|
||
|
|
8f66fafb90 |
Merge pull request 'fix(pf-vdisplay): verify the size KWin actually built the virtual output at (≤60 Hz path)' (#194) from worktree-moonlight-4k60-dims into main
android / android (push) Canceled after 0s
arch / build-publish (push) Canceled after 0s
ci / rust (push) Canceled after 0s
ci / rust-arm64 (push) Canceled after 0s
ci / web (push) Canceled after 0s
ci / docs-site (push) Canceled after 0s
ci / bun-nix (push) Canceled after 0s
deb / build-publish (push) Canceled after 0s
deb / build-publish-host (push) Canceled after 0s
deb / build-publish-gamescope (push) Canceled after 0s
deb / build-publish-client-arm64 (push) Canceled after 0s
deb / smoke-install (push) Canceled after 0s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Canceled after 0s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Canceled after 0s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Canceled after 0s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Canceled after 0s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Canceled after 0s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Canceled after 0s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Canceled after 0s
docker / builders-arm64cross (push) Canceled after 0s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Canceled after 0s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 0s
docker / deploy-docs (push) Canceled after 0s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 0s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 0s
windows-host / package (push) Successful in 12m40s
windows-host / winget-source (push) Skipped
windows-host / canary-manifest (push) Successful in 26s
Reviewed-on: #194 |
||
|
|
6fe53fff2b |
Merge pull request 'Serialize Mutter monitor rebuilds end-to-end — the two-client chain no longer segfaults gnome-shell' (#195) from worktree-mutter-rebuild-serialization into main
android / android (push) Canceled after 35s
arch / build-publish (push) Canceled after 0s
ci / rust (push) Canceled after 0s
ci / rust-arm64 (push) Canceled after 0s
ci / web (push) Canceled after 0s
ci / docs-site (push) Canceled after 0s
ci / bun-nix (push) Canceled after 0s
deb / build-publish (push) Canceled after 0s
deb / build-publish-host (push) Canceled after 0s
deb / build-publish-gamescope (push) Canceled after 0s
deb / build-publish-client-arm64 (push) Canceled after 0s
deb / smoke-install (push) Canceled after 0s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Canceled after 0s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Canceled after 0s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Canceled after 0s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Canceled after 0s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Canceled after 0s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Canceled after 0s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Canceled after 0s
docker / builders-arm64cross (push) Canceled after 0s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Canceled after 0s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 0s
docker / deploy-docs (push) Canceled after 0s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 0s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 0s
windows-host / package (push) Canceled after 0s
windows-host / canary-manifest (push) Canceled after 0s
windows-host / winget-source (push) Canceled after 0s
Reviewed-on: #195 |
||
|
|
1679275272 |
fix(flatpak): pin the skia-binaries archive to 0.99.0 — #193 bumped the crate and left the tarball at 0.87
ci / bun-nix (pull_request) Successful in 26s
ci / docs-site (pull_request) Successful in 1m19s
ci / rust-arm64 (pull_request) Successful in 1m47s
ci / web (pull_request) Successful in 3m23s
android / android (pull_request) Successful in 5m16s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 7m3s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 2m57s
ci / rust (pull_request) Successful in 8m51s
The dependency currency wave took skia-safe/skia-bindings 0.87.0 -> 0.99.0 in
crates/pf-console-ui/Cargo.toml, but packaging/flatpak/io.unom.Punktfunk.yml still
pinned the 0.87.0 prebuilt archive, so every flatpak leg since the merge dies with
error[E0599]: no variant, associated function, or constant named `Default`
found for enum `SkPathFillType` (and `SkPathDirection`)
--> cargo/vendor/skia-bindings-0.99.0/src/defaults.rs:57
Nothing about that message points at the manifest, so it reads like a crate bug. It
isn't. `SKIA_BINARIES_URL: file://…` makes skia-bindings unpack the pinned tarball
verbatim into target/…/build/skia-bindings-*/out/skia/ — *including the bindings.rs
it was generated with*. Those two `Default`s are associated consts emitted INTO
bindings.rs, so they travel with the archive, not with the crate: 0.99.0's
src/defaults.rs was compiling against 0.87.0-era bindings. Verified directly — the
0.99.0 archive carries `impl SkPathFillType { pub const Default = Winding }` and
`impl SkPathDirection { pub const Default = CW }` on both x86_64 and aarch64.
Because the URL is file://, the fetch can never fail, so there is no download error
to notice — the only symptom is a compile error deep in a vendored crate.
The asset name changed across the bump: `jpeg` entered skia-safe's defaults at 0.99,
so the resolved-feature key went `pdf-textlayout-vulkan` -> `jpegd-jpege-pdf-textlayout-vulkan`.
Confirmed against each archive's own key.txt/tag.txt (tag 0.99.0, key
a25a0fdb7d90429aa2d1-<target>-jpegd-jpege-pdf-textlayout-vulkan), and libskparagraph.a
plus the Vulkan backend symbols are present, so the feature set still matches what
pf-console-ui resolves.
Everything else in the offline chain (Cargo.lock, cargo-sources.json) is regenerated
from the lock and self-corrects; this tarball is the single hand-maintained pin, which
is exactly why it was the thing left behind. Both bump sites now carry a pointer to
the other so the next one can't split-brain the same way.
|
||
|
|
a5c9b7b865 |
fix(pf-vdisplay): serialize Mutter monitor rebuilds end-to-end, not just our D-Bus calls
ci / web (pull_request) Successful in 1m17s
ci / bun-nix (pull_request) Successful in 1m24s
ci / docs-site (pull_request) Successful in 1m27s
android / android (pull_request) Successful in 4m36s
ci / rust-arm64 (pull_request) Successful in 6m14s
ci / rust (pull_request) Successful in 33m50s
Chaining two clients through a kept (keep-alive) Mutter display segfaults gnome-shell in meta_monitor_manager_rebuild (libmutter-18) and takes the whole desktop down; every later session then fails RemoteDesktop.CreateSession: ServiceUnknown until GDM restarts. A/B'd on .21: byte-identical on released 0.27.0 and the 0.28.0 RC, so it was never a regression — the trigger has been there all along. TOPOLOGY_LOCK already serialized every topology-mutating D-Bus call, but two gaps still let Mutter's REBUILDS overlap: - Teardown was fire-and-forget: StopGuard::drop set a flag and returned, and the session thread only noticed on its ≤200 ms park tick. The A2 dead-reuse path (reused kept display dead on first frame → mark_failed → re-create) therefore issued its fresh RecordVirtual with the doomed monitor's removal still pending — the fresh session could even win the lock BEFORE the old thread had woken to take it, adding a monitor while the dead one still stood. The drop now waits (bounded, 20 s) for the session thread to finish. - The lock was released while the shell was still rebuilding: Stop / RecordVirtual / ApplyMonitorsConfig all return mid-rebuild, and a temporary (APPLY_TEMPORARY) config auto-reverts asynchronously on top. Every locked mutation section now ends with settle_topology() — poll GetCurrentState until a removed connector is actually gone and the config serial holds still across two consecutive reads — before the guard drops. Bounded at 4 s and best-effort (a read error means the shell is gone; a hotplug storm must not park sessions), degrading to exactly the old behavior. Cost when Mutter is already quiet: one confirming read plus one 150 ms recheck per setup/teardown. The live_mutter_create_drop harness sheds its grace sleep — the synchronous drop IS the teardown confirmation now. Not fixed here, documented on TOPOLOGY_LOCK: the mid-stream mode-switch rebuild is create-before-drop by design (H2), so its RecordVirtual still lands while the superseded monitor exists; the settle makes Mutter quiescent at that point but cannot remove the coexistence itself. |
||
|
|
6237e3d0a3 |
fix(pf-vdisplay): the KWin ≤60 Hz path never checked what KWin actually built, and the log reported the request as if it were a readback
ci / bun-nix (pull_request) Successful in 37s
ci / web (pull_request) Successful in 1m14s
ci / docs-site (pull_request) Successful in 2m31s
ci / rust-arm64 (pull_request) Successful in 4m14s
android / android (pull_request) Successful in 4m53s
ci / rust (pull_request) Successful in 25m8s
A 4K60 GameStream session captured 1920x1080. `create()` asked KWin for
3840x2160, KWin built something else, and nothing compared the two: only the
>60 Hz arm read anything back, and it gets that for free because it installs a
custom mode. The ≤60 Hz arm installs nothing, which is exactly why it never
noticed.
The line that should have caught it was the one that hid it. `spawn_vout`
returns a node id, never a size, so
tracing::info!(node_id, width, height, "KWin virtual output ready")
was echoing the REQUEST — the field log stated 3840x2160 while the output was
1080p, and the first pass at diagnosing this was done against that number. It
now logs `requested_w`/`requested_h`, and the readback sits under it.
Unverified, the mismatch was silent and total. `final_dims` carried the request
forward, so `apply_topology`, `clear_replication_source` and
`resolve_kscreen_addr` — all of which resolve by dims — quietly missed their own
output, leaving the stream neither primary nor de-mirrored; and the encoder
opened at the captured size, handing the client a bitstream that disagreed with
the resolution it had configured its decoder from.
Suspected trigger is KWin restoring per-output mode/scale from
kwinoutputconfig.json, which is keyed by output NAME — and ours is deliberately
stable across sessions so KDE reapplies that client's scaling (Stage 3). The
feature and the failure are the same mechanism.
- `kwin_output_mgmt::actual_dims()` reads the output's real mode + scale.
Resolution is by name alone, so it declines unless EXACTLY one output carries
our prefix: two means a supersede is in flight, and the dims filter is the
only thing that can tell the replacement from the predecessor whose name it
reuses. Failing closed keeps this a pure addition.
- On a mismatch, re-assert the requested mode through the same
`set_custom_mode` install+select the sacrificial birth already uses (an output
at a size we don't want, moved to one we do) and arm `expect_exact_dims` so
the capturer holds frames until the screencast renegotiates. 60 Hz is
requested, not `mode.refresh_hz`: only the size is wrong here, and asking for
the client's rate would install a 30 Hz mode for a 30 fps client.
- If KWin refuses the correction, report the size that is REALLY there rather
than the request, so the dims-keyed resolves and the encoder key on reality,
and say in the log how to clear the stored entry.
- Scale is logged, never corrected — a non-unity scale here is the Stage 3
feature working, not a fault.
- `mode_satisfies()` extracts the acceptance predicate both arms now share, so
they cannot drift into disagreeing about what "we got what we asked for"
means. Tested: a restored 1080p does not pass for a 4K request, a CVT-aligned
width does, and the slack is bounded, one-sided and width-only.
The stream-side warning is reworded but deliberately still NOT fatal: mirroring
a pinned monitor streams a size the client never negotiated BY DESIGN (§7.3 — a
panel runs at the mode its owner set and the client scales), so refusing the
mismatch would break every mirror session. It now names both causes and states
what the client actually does with the stream.
Does not claim to close the Xbox Moonlight disconnect it was found through: that
client's IDR storm begins ~4.6 s after the first frame, which a decoder simply
unable to handle the size would not do. The 1080p-instead-of-4K is a real defect
on its own terms and is what this fixes.
|
||
|
|
14425716e5 |
Merge pull request 'Dependency currency wave: skia-safe 0.99, the RustCrypto digest-0.11 family, jni 0.22 and ten more — plus the notices they invalidated' (#193) from worktree-dep-currency-wave into main
apple / swift (push) Successful in 2m0s
audit / cargo-audit (push) Successful in 2m45s
audit / bun-audit (plugin-kit) (push) Successful in 43s
audit / bun-audit (sdk) (push) Successful in 38s
audit / bun-audit (web) (push) Successful in 19s
audit / pnpm-audit (push) Successful in 13s
audit / docs-site-audit (push) Successful in 31s
android / android (push) Successful in 8m25s
audit / license-gate (push) Successful in 5m42s
audit / miri (push) Successful in 7m59s
apple / distribute (push) Successful in 12m31s
audit / c-abi-asan (push) Successful in 7m8s
ci / bun-nix (push) Successful in 26s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m23s
ci / docs-site (push) Successful in 2m2s
ci / rust-arm64 (push) Successful in 5m51s
ci / web (push) Successful in 6m18s
arch / build-publish (push) Successful in 20m52s
apple / screenshots (push) Successful in 6m55s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Failing after 1m18s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 6m53s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 5m51s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4m30s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 1m2s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 6m53s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 3m58s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m38s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Successful in 7m9s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 7m7s
docker / builders-arm64cross (push) Skipped
docker / deploy-docs (push) Failing after 2m35s
windows-host / package (push) Successful in 18m44s
windows-host / winget-source (push) Skipped
deb / build-publish (push) Successful in 7m9s
deb / build-publish-gamescope (push) Successful in 4m42s
deb / build-publish-client-arm64 (push) Successful in 4m6s
windows-host / canary-manifest (push) Successful in 45s
ci / rust (push) Successful in 31m28s
flatpak / build-publish (push) Failing after 15m23s
nix / flake (push) Successful in 16m36s
deb / build-publish-host (push) Successful in 10m13s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 18m31s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Failing after 2m9s
deb / smoke-install (push) Successful in 10m18s
Reviewed-on: #193 |
||
|
|
4903c9d3b5 |
docs(host): the P-256 identity comment still named ring's backend
ci / docs-site (pull_request) Successful in 1m25s
apple / swift (pull_request) Successful in 2m15s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
ci / bun-nix (pull_request) Successful in 2m33s
ci / web (pull_request) Successful in 3m26s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 6m20s
android / android (pull_request) Successful in 7m34s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 9m4s
ci / rust-arm64 (pull_request) Successful in 16m13s
nix / flake (pull_request) Successful in 16m36s
ci / rust (pull_request) Successful in 47m49s
#192 moved rcgen to aws-lc-rs and removed ring from the tree, but this comment still explained the P-256 path in terms of "rcgen's ring backend". It also cross-references gamestream::cert's note, which this branch already corrected — so leaving it made the two contradict each other. The substance is unchanged and still load-bearing: rcgen generates EC keys directly, while RSA has to be generated by the `rsa` crate and handed to rcgen to self-sign, because no rcgen backend will generate an RSA key. |
||
|
|
a4af1ee8bd |
chore(deps): regenerate third-party notices for the currency wave
Covers all five generated files, not just the root one: the four per-client copies are scoped to the binaries their package installs, so they move independently of the workspace-wide file. Root: 571 -> 575 crates, reflecting this wave (skia-safe 0.99, the RustCrypto digest-0.11 family, jni 0.22, x11rb 0.14, reis 0.7, xkbcommon 0.9, wasapi 0.24, windows-service 0.8.1, x509-parser 0.18, rand 0.9, base64 0.23, libloading 0.9, mdns-sd 0.21 + if-addrs 0.15, rcgen 0.14, criterion 0.8, android_logger 0.15). The per-client diffs are much larger than the wave alone explains, because they were never regenerated after #192: all four still attributed `ring` and named no aws-lc-rs at all. Since #192 removed ring from the tree entirely, the shipped Acknowledgements screens have been crediting a crypto library the clients do not carry while omitting the one they do. They now catch up on both changes at once. (`ring` still appears via the generator's deliberate `--all-features` over-approximation, which sees quinn-proto's wasm-only edge; that is by design — listing an unlinked crate is untidy, omitting a linked one is the failure the file exists to prevent.) Also stops gen-third-party-notices.sh preferring `cargo about` for the root file. That preference was silently destructive: cargo-about only sees CARGO dependencies, so it drops every VENDORED_TREES entry -- pyrowave, the Granite subset, volk, Vulkan-Headers, the Font Awesome brand icons, Simple Icons -- which are third-party sources shipped inside first-party crates under their own licences. Measured today: cargo-about emitted 7,274 lines / ~514 crates with zero mentions of volk, Vulkan-Headers or Font Awesome, against the python generator's 17,324 / 575 with all of them. Merely having cargo-about on PATH was enough to degrade the file, so anyone regenerating after this commit would have undone it. cargo-about remains what the CI licence gate runs -- that job asks a different question (is every licence in the about.toml allowlist) and writes to /dev/null. Both licence-gate legs pass: `cargo about generate about.hbs --fail` and the drivers-workspace leg, RC=0. |
||
|
|
5cd4da4b46 |
Merge branch 'worktree-agent-a3a9cb8eda476b361' into worktree-dep-currency-wave
# Conflicts: # Cargo.lock # crates/punktfunk-host/Cargo.toml |
||
|
|
59346b46dc | Merge branch 'worktree-agent-acec77fec2148a724' into worktree-dep-currency-wave | ||
|
|
76b80cffb5 | Merge branch 'worktree-agent-aaab7ab43ea5de9c8' into worktree-dep-currency-wave | ||
|
|
9e492bfec3 | Merge branch 'worktree-agent-a5cf35a576dde87f5' into worktree-dep-currency-wave | ||
|
|
692bfbaa4f | Merge branch 'worktree-agent-a220ca550d5f8734b' into worktree-dep-currency-wave | ||
|
|
f9932e0873 | Merge branch 'worktree-agent-a61772a0f20a2e4f1' into worktree-dep-currency-wave | ||
|
|
bd987d373e |
chore(deps): criterion 0.5 -> 0.8 (dev-only, benches)
Dev-dependency of punktfunk-core only — it ships in nothing. `default-features =
false, features = ["cargo_bench_support"]` carries over unchanged; that feature
still exists in 0.8 and still keeps plotters/rayon out of a headless CI run.
One source change, and it is a lint issue rather than an API one.
`criterion::black_box` survives in 0.8 but is `#[deprecated]` — it now just
forwards to `std::hint::black_box` — and benches ARE compiled by
`cargo clippy --workspace --all-targets -- -D warnings`, so keeping the criterion
import would have turned a deprecation warning into a failed lint gate. The
bench imports the std one directly.
What CI actually consumes from criterion is the on-disk result layout, so that
was checked rather than assumed: 0.8 still writes
`target/criterion/<group>/<id>/new/estimates.json`, and the key
scripts/bench/compare.py reads — `median.point_estimate` — is still there:
$ cargo bench -p punktfunk-core --bench pipeline -- --warm-up-time 1 --measurement-time 3
... 12/12 benchmarks reported, e.g. pipeline/gf16/1048576 thrpt: [537 MiB/s 540 MiB/s 542 MiB/s]
$ find target/criterion -name estimates.json | wc -l
24
$ python3 -c 'import json; print(json.load(open(".../crypto/seal/new/estimates.json"))["median"]["point_estimate"])'
817.96
Verified on CachyOS (rustc 1.96.0):
cargo clippy -p punktfunk-core --all-targets --locked -- -D warnings OK (this is what compiles the bench)
cargo clippy --workspace --all-targets --locked -- -D warnings OK
cargo bench -p punktfunk-core --bench pipeline --locked -- --test 12/12 Success
cargo bench -p punktfunk-core --bench pipeline --locked -- --warm-up-time 1 --measurement-time 3 OK (CI's exact line)
cargo test -p punktfunk-core --locked 210 + 8 + 1 passed, 0 failed
cargo fmt --all --check clean
|
||
|
|
deb83ecc48 |
chore(deps): rcgen 0.13 -> 0.14 in core and the host
Both declarations keep `default-features = false, features = ["aws_lc_rs",
"pem"]`, which stays load-bearing in 0.14: `ring` is still in rcgen's DEFAULT
feature set, so dropping `default-features = false` would drag the backend this
tree deliberately left back in. Verified after the bump — `cargo tree -i ring`
finds nothing on x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc,
aarch64-apple-darwin or aarch64-linux-android.
One breaking change reached us. `CertifiedKey`'s key field was renamed
`key_pair` -> `signing_key` (the struct is now generic, `CertifiedKey<S:
SigningKey>`), which hits the two `generate_simple_self_signed` callers in
core's quic/endpoint.rs — the dev/test server endpoint and `generate_identity`.
Both are a field rename; `KeyPair` still provides `serialize_der`/`serialize_pem`.
Everything the GAMESTREAM identity depends on survives unchanged, which is what
this bump's precondition was about: `KeyPair::from_pkcs8_pem_and_sign_algo`,
`PKCS_RSA_SHA256`, `CertificateParams::new`, `date_time_ymd`, `self_signed`,
`Certificate::pem`. The split in gamestream/cert.rs is therefore untouched — the
RSA-2048 key is still minted by the `rsa` crate and handed to rcgen only to load
and self-sign, because rcgen cannot generate an RSA key on the backend we use.
That path is asserted, not assumed:
cargo test -p punktfunk-host --bins --locked gamestream::cert 3 passed, 0 failed
generate_mints_a_loadable_rsa2048_identity ok (fresh-install keygen)
moonlight_shaped_peer_completes_a_tls12_mutual_handshake ok
tls13_negotiates_the_post_quantum_group ok (X25519MLKEM768 by name)
Verified on CachyOS (rustc 1.96.0):
cargo clippy --workspace --all-targets --locked -- -D warnings OK
cargo clippy -p punktfunk-host -p punktfunk-core --locked -- -D warnings OK (shipping build)
cargo test --workspace --locked 78 test binaries, all ok, 0 failed
cargo fmt --all --check clean
|
||
|
|
2718b7d4bd |
chore(deps): mdns-sd 0.20 -> 0.21 and if-addrs 0.13 -> 0.15, together
One commit because splitting them accomplishes nothing: mdns-sd 0.20 ALREADY
depends on if-addrs 0.15, so while our own five crates declared 0.13 the tree
carried both copies no matter which of the two moved first. Moving them together
is what collapses it:
$ cargo tree -d | grep '^if-addrs'
(no output)
Neither needed a source change. mdns-sd 0.21's public API is purely additive
over 0.20.3 — the sole new item is `ServiceDaemon::set_max_packet_size`, and
`ServiceInfo`'s surface is byte-identical — so `ServiceDaemon`/`ServiceInfo`/
`ServiceEvent`/`ResolvedService` behave as before at all six call sites
(host discovery + gamestream mdns, pf-client-core, and the Android, Windows and
probe clients). if-addrs 0.15 keeps 0.13's `Interface`/`IfAddr` shape, and we
only ever read those.
The one real change is a FEATURE, not a version. if-addrs has `link-local`, and
mdns-sd declares if-addrs with it on. Once our crates share that single copy,
unification turns it on for our calls too — meaning `get_if_addrs()` now also
reports fe80:: interfaces (and, on Windows, 169.254.x.x). Rather than inherit
that silently, punktfunk-core and punktfunk-host now NAME the feature. Two
reasons: it is what every real build gets anyway, so a standalone `cargo test -p
punktfunk-core` should not enumerate a different set of NICs than the host does;
and for the consumer here — Wake-on-LAN — it is the behaviour we want, since a
NIC is wake-capable whether or not it currently holds a routable address.
Verified on CachyOS (rustc 1.96.0):
cargo clippy --workspace --all-targets --locked -- -D warnings OK
cargo test --workspace --locked OK, 0 failed
cargo test -p punktfunk-host --bins --locked 501 passed, 0 failed, 2 ignored
cargo test ... gamestream::cert 3 passed
cargo fmt --all --check clean
(One `cargo test --workspace` attempt failed with E0463 "can't find crate for
pf_frame" in a doc-test. That is the target dir having only clippy's .rmeta for
a crate a doc-test wants to LINK, not anything in this change; a plain re-run
after cargo test built the rlibs was green.)
|
||
|
|
99c3a47bbf |
chore(deps): libloading 0.8 -> 0.9 across the five crates that dlopen
All five declarations move together (pf-encode twice — Linux and Windows —
plus pf-client-core, pf-zerocopy and punktfunk-host), because a split would
have compiled two copies of a crate whose whole job is holding a process-wide
dlopen handle.
No source changes. 0.9 replaces the concrete parameter types with sealed traits
— `Library::new(impl AsFilename)` and `Library::get(impl AsSymbolName)` — and
both cover what our 16 call sites already pass: `&str` literals for the sonames
(`libnvidia-encode.so.1`, `libva.so.2`, `libnvidia-ml.so.1`, `libcuda.so.1`) and
`&[u8; N]` NUL-terminated byte literals for the symbols, which 0.9 implements
explicitly alongside `&[u8]`. MSRV rises to 1.88; the workspace pins 1.96.
libloading 0.8 does not leave the lock, and shouldn't: what remains is
`clang-sys` under `bindgen`, reached only as a BUILD-dependency of
ffmpeg-sys-next / libspa-sys / pyrowave-sys. That copy runs at build time and is
linked into nothing we ship.
Verified on CachyOS (rustc 1.96.0):
cargo clippy --workspace --all-targets --locked -- -D warnings OK
cargo clippy -p pf-encode --all-targets --locked --features nvenc,vulkan-encode,pyrowave -- -D warnings OK
(the only leg that compiles enc/linux/nvenc_cuda.rs, where the `lib.get(b"…\0")` calls live)
cargo clippy -p punktfunk-host -p pf-encode -p pf-zerocopy -p pf-client-core --locked -- -D warnings OK (shipping build)
cargo test -p punktfunk-host --bins --locked 501 passed, 0 failed, 2 ignored
cargo test -p pf-encode --locked 33 passed, 5 ignored
cargo test -p pf-zerocopy --locked 40 passed
cargo fmt --all --check clean
|
||
|
|
677b8ceb41 |
chore(deps): base64 0.22 -> 0.23 in the host and pf-update-check
ureq 3 already pulls 0.23, so the tree compiled both minors purely because our two direct declarations named the older one. The API we use — `Engine`, `engine::general_purpose::STANDARD`, `encode`/`decode` — is unchanged in 0.23; no source edits. Both are declared `default-features = false, features = ["std"]` rather than taking the defaults. 0.23 added `simd-unsafe` (hand-written AVX2/NEON engines) as a DEFAULT-ON feature, and ureq declares base64 with default features off, so today that code is not in the tree. Accepting the defaults here would unify the feature on and quietly add an unsafe SIMD engine to every artifact as a side effect of a currency bump. Whether to enable it is a perf question deserving a measurement and its own commit; this one changes versions, not exposure. `std` covers every call site (encode to `String`, decode to `Vec`). base64 0.22 does NOT leave the tree: `rcgen` -> `pem` 3.0.6 is now its sole remaining consumer, and it stays one after the rcgen 0.14 bump later in this batch — 0.14 still depends on `pem` "3.0.2", which resolves to the same 3.0.6, which still uses base64 0.22. Clearing that last copy is upstream's move (a `pem` release on 0.23), not ours. Verified on CachyOS (rustc 1.96.0): cargo clippy -p punktfunk-host -p pf-update-check --locked --all-targets -- -D warnings OK cargo clippy -p punktfunk-host -p pf-update-check --locked -- -D warnings OK (shipping build) cargo test -p punktfunk-host --bins --locked 501 passed, 0 failed, 2 ignored cargo test -p pf-update-check --locked 32 passed, 0 failed cargo fmt --all --check clean |
||
|
|
4358261387 |
chore(deps): rand 0.8 -> 0.9 in the host, the last crate speaking the old major
punktfunk-core and pf-client-core were already on 0.9; the host sat on 0.8 by
drift, not by decision, so every build compiled two rand majors to satisfy six
call sites. Mechanical at five of them (`thread_rng()` -> `rng()`,
`gen_range` -> `random_range`); the sixth is the interesting one.
`RsaPrivateKey::new` is bounded on rand_core **0.6**'s `CryptoRngCore`. rand
0.9's `ThreadRng` implements rand_core 0.9's traits — same names, different
crate — so the RSA-2048 keygen in gamestream/cert.rs stopped satisfying the
bound the moment the version moved. It now draws from `rsa::rand_core::OsRng`:
rsa's own re-export, which is by construction the traits rsa compiled against,
so the two rand_core majors never have to meet in our source. That needs
`features = ["getrandom"]` on rsa (not one of its defaults) — and it must be
declared HERE rather than left to feature unification, because dropping our own
rand 0.8 also dropped the `std` feature that used to switch `rand_core/getrandom`
on as a side effect.
What this does and does not clear. The GAMESTREAM host keeps rand 0.8 +
rand_chacha 0.3 — `rsa` drags them in through `num-bigint-dig`, which is not
ours to move:
$ cargo tree -i rand@0.8.7
rand v0.8.7
└── num-bigint-dig v0.8.6
└── rsa v0.9.10
└── punktfunk-host
The NATIVE-ONLY host (--no-default-features, no rsa) now sheds both entirely —
`cargo tree -p punktfunk-host --no-default-features --features pyrowave -i
rand@0.8.7` and the same for rand_chacha@0.3.1 both report no match. rand_core
0.6 stays in every flavour regardless: `crypto-common` (under aes-gcm) needs it,
which no rand bump can change.
`windows/install.rs`'s `random_password` is the one site a Linux box cannot
type-check; the edit there is the identical `thread_rng()` -> `rng()` the five
compiled sites took.
Verified on CachyOS (rustc 1.96.0):
cargo clippy -p punktfunk-host --locked --all-targets -- -D warnings OK
cargo clippy -p punktfunk-host --locked -- -D warnings OK (shipping build: no --all-targets)
cargo clippy -p punktfunk-host --no-default-features --features pyrowave --all-targets --locked -- -D warnings OK
cargo test -p punktfunk-host --bins --locked 501 passed, 0 failed, 2 ignored
cargo test ... gamestream::cert 3 passed (incl. the fresh-install RSA-2048 keygen)
cargo fmt --all --check clean
|
||
|
|
8020fb6711 |
chore(deps): x509-parser 0.16 -> 0.18, and thiserror 1.0 leaves the host graph
x509-parser 0.16 pinned the old asn1-rs 0.6 / der-parser 9 / oid-registry 0.7
chain, and every one of those still depended on thiserror 1.0. It was the ONLY
thing doing so — so the host compiled two thiserror majors (and two
thiserror-impl proc macros) for one crate's error types. 0.18 moves the chain to
asn1-rs 0.7 + thiserror 2, which is the same major the rest of the tree already
uses, and the 1.0 half disappears — for the host, on every target and including
dev-dependencies:
$ cargo tree -p punktfunk-host --target all -e normal,build,dev -i thiserror@1
error: package ID specification `thiserror@1` did not match any packages
Scope that claim honestly: this clears the HOST graph, not the workspace.
thiserror 1.0 is still built, reached by `jni` 0.21 AND by the vendored
`ndk` 0.9.0, both under punktfunk-client-android. That is a different graph
and a different bump.
No source change was needed. The one API shift that could have reached us —
asn1-rs 0.7 making `BitString::data` a `Cow<[u8]>` instead of a `&[u8]` — lands
on `x509.signature_value.data.to_vec()` in gamestream/cert.rs and
gamestream/pairing.rs, and `to_vec()` goes through Deref either way. Both are
Moonlight pairing-hash inputs, so they are covered by the gamestream::cert
tests rather than taken on faith. nom 7 and nom 8 were already both in the lock;
this adds no new duplicate.
Verified on CachyOS (rustc 1.96.0):
cargo clippy -p punktfunk-host --locked --all-targets -- -D warnings OK
cargo clippy -p punktfunk-host --locked -- -D warnings OK (shipping build: no --all-targets)
cargo clippy -p punktfunk-host --no-default-features --features pyrowave --all-targets --locked -- -D warnings OK
cargo test -p punktfunk-host --bins --locked 501 passed, 0 failed, 2 ignored
cargo test ... gamestream::cert 3 passed
cargo tree -i ring nothing to print
|
||
|
|
49a8f4f1d1 |
chore(deps): xkbcommon 0.8 -> 0.9
Version currency for the virtual-keyboard keymap in pf-inject's wlroots path
(`inject/linux/wlr.rs`), the crate's only consumer.
Additive on the Rust side: one new wrapper, `Keymap::key_get_mods_for_level`,
and the `extern` declaration behind it. Nothing we call changed shape -- we use
`Context::new`, `Keymap::new_from_names`, `get_as_string`, `State::new`,
`Keycode::new`, `KeyDirection` and the `serialize_mods`/`serialize_layout` pair,
all untouched. The feature set is unchanged too: `default = ["wayland"]` in both
releases, so `x11` -- the feature that would pull `as-raw-xcb-connection` -- stays
off and this links only `libxkbcommon`, exactly as before.
The one thing worth writing down is the new symbol's floor. On .25's
libxkbcommon 1.13.1 it reads
`xkb_keymap_key_get_mods_for_level@@V_1.0.0`, so the declaration wants
libxkbcommon >= 1.0.0 (2020) if it is ever referenced. Nothing in the workspace
calls the wrapper, so no relocation for it reaches our binaries -- and every ship
target clears 1.0 by years regardless (Ubuntu 22.04 is 1.4, Debian 12 is 1.5,
Debian 13 is 1.7). pf-inject's test binary, which unlike the rlib actually links,
builds and runs clean.
Two internal fixes come along, both in constructors we do not use:
`new_from_string` passes the Rust string's pointer + length to
`xkb_keymap_new_from_buffer` instead of round-tripping through a `CString`
(whose `unwrap()` panicked on an interior NUL), and `new_from_fd` passes the
full mapped `size` rather than `size - 1`.
Verified on .25 (Ubuntu 26.04, `CARGO_BUILD_JOBS=2`), all rc=0:
cargo build -p pf-inject --locked
cargo clippy -p pf-inject --locked -- -D warnings
cargo clippy -p pf-inject --all-targets --locked -- -D warnings
cargo test -p pf-inject --locked 127 passed, 0 failed, 8 ignored
+ motion_contract: 7 passed, 0 failed
cargo check -p punktfunk-host --locked
cargo clippy -p punktfunk-host --locked -- -D warnings
cargo fmt --all --check
Clippy is run BOTH ways because host CI lints without `--all-targets`.
`cargo tree -i ring` stays empty.
|
||
|
|
72c7c3b17f |
chore(deps): reis 0.6.1 -> 0.7.1
Version currency for the libei path. pf-inject is the only consumer -- reis is a
pure-Rust implementation of the EI wire protocol, so this links nothing new and
still needs no libei on the host. The release tracks libei protocol 1.5.0 ->
1.6.0.
**Nothing in our API surface moved.** `ei::Context::new`, `handshake_tokio`,
`reis::tokio::EiConvertEventStream` and `reis::event::{Device, DeviceCapability,
EiEvent, Region}` all keep their shape; `Region`'s six fields are byte-identical.
The two enums grew variants for libei 1.6's `ei_text` (`EiEvent::TextKeysym` /
`TextUtf8`, `DeviceCapability::Text`), which compiles because `handle_ei`'s match
ends in `_ => {}` and the capability set we bind is written out explicitly. The
handshake now ADVERTISES `ei_text` as a supported interface, so a 1.6 EIS may
offer one; we never bind it and never emit on it.
**Behaviour we inherit, all of it upstream bug fixes:**
- Frames now commit per device. 0.6 held one global pending queue, so an
`ei_device.frame` from device A committed device B's timestamped events under
A's timestamp. Inert for us -- we are an EI *sender*, and the events we
receive are device lifecycle plus `KeyboardModifiers`, none of which are the
timestamped kind that queue -- but strictly more correct.
- `Device::interface()` now forgets an interface when the server sends its
`destroyed` event, and `DeviceRemoved` un-registers the device's interfaces
from the converter's reverse map. Our `slot.interface::<ei::Button>()` and
friends therefore stop handing back a proxy for a torn-down interface instead
of emitting into a dead object.
- `Device`, `Seat` and `Object` now hash consistently with their `PartialEq`.
Both were already `Arc::ptr_eq`; `Hash` used the protocol object id, which is
a broken pair. We keep devices in a `Vec` and compare with `==`/`!=`, so this
changes nothing here.
- The wire backend rejects a header length above libei's 1 MiB `max_msglen`
BEFORE waiting for that many bytes, so a malformed length no longer parks the
reader until the connection dies.
**The host graph loses the `futures` facade crate.** reis's `tokio` feature
depended on `futures`; 0.7 depends on `futures-util` directly, which pf-inject
already declares. `cargo tree --target all -i futures` now names only relm4 (the
GTK Linux client), and `futures` + `futures-executor` are gone from
punktfunk-host's Linux tree (`futures-task` stays, under futures-util). Lockfile
delta is one package: `reis` 0.6.1 -> 0.7.1 with `futures` -> `futures-util` in
its dep list; the workspace package SET is unchanged, since relm4 and glib still
need those crates for the GTK client.
Verified on .25 (Ubuntu 26.04, `CARGO_BUILD_JOBS=2`), all rc=0:
cargo build -p pf-inject --locked
cargo clippy -p pf-inject --locked -- -D warnings
cargo clippy -p pf-inject --all-targets --locked -- -D warnings
cargo test -p pf-inject --locked 127 passed, 0 failed, 8 ignored
+ motion_contract: 7 passed, 0 failed
cargo check -p punktfunk-host --locked
cargo clippy -p punktfunk-host --locked -- -D warnings
cargo fmt --all --check
Clippy is run BOTH ways because host CI lints without `--all-targets`.
`cargo tree -i ring` stays empty.
|
||
|
|
d73bdcdcc1 |
chore(deps): jni 0.21 → 0.22 for the Android JNI bridge
Version currency, but a real API migration rather than a version-number edit — and the
payoff is bigger than "one crate is newer", because jni 0.22 was ALREADY in this .so:
`rustls-platform-verifier` (via quinn-proto, for Android cert verification) depends on it,
so pinning 0.21 here compiled two complete jni copies into one library. Matching the
version collapses them.
Eliminated, measured as the delta in THIRD-PARTY-NOTICES.txt (582 → 571 crates, nothing
added): jni 0.21.1, its `cesu8`, and — because jni 0.21 was the SOLE consumer of
windows-sys 0.45.0, the oldest crate in the tree — that whole windows-rs 0.42 generation:
windows-sys 0.45.0, windows-targets 0.42.2 and its seven per-arch import libraries. Eleven
crates, carried for a `cfg(windows)` dependency of an Android-only bridge.
NOT eliminated, contrary to what the sweep expected — recorded in the manifest so the next
person does not re-derive it. thiserror 1.0 and the jni-sys 0.3/0.4 split both survive,
because jni was never their only source:
thiserror 1.0.69 ← vendor/ndk 0.9.0 (+ asn1-rs/x509-parser, host side)
jni-sys 0.3.1 ← vendor/ndk 0.9.0 AND crates.io ndk-sys 0.6
jni's share of both is gone; the remainder is the ndk stack. jni-sys 0.3.1 is itself a
facade crate over 0.4.1, so the split cannot close until ndk and ndk-sys move, and `ndk` is
vendored for a one-line visibility patch — changing its dependency versions would mean
rewriting the vendored snapshot instead of reading it as a diff against upstream. Left
alone deliberately.
The migration itself, across 66 native methods in 10 files:
* `JNIEnv` split into `EnvUnowned` (the FFI-safe native-method argument) and `Env` (where
the JNI calls live). The 41 methods that never touched the environment are a type
rename; the 22 that do now acquire an `Env` inside `EnvUnowned::with_env` and map the
outcome with an `ErrorPolicy`.
* `LogErrorAndDefault` everywhere, chosen to PRESERVE behaviour: the old code swallowed
JNI errors and returned a default, and this logs and returns the same default. The
throwing policy would have been a behaviour change (new Java exceptions out of methods
that previously failed quietly), which is not what a currency bump should do.
* `with_env` also catches panics, which is exactly what the crate's own `jni_guard` did,
so the guard is folded into it where the two would have nested. It stays on the methods
that take no `Env`. ONE exception, marked at the call site: `nativeNextHidout` returns
-1 as its failure sentinel, and every error policy resolves to `T::default()` — which
for `jint` is 0, a *valid* byte count. That method keeps `jni_guard(-1, …)` outside and
uses `with_env_no_catch` inside so the sentinel survives the panic path unchanged.
* `jboolean` is `bool` in jni-sys 0.4, not `u8` — a type change, not a rename, and the
reason for most of the mechanical diff (`down != 0` → `down`, `return 0` → `false`).
* `Env::get_string` is deprecated in favour of `JString::try_to_string`, and CI runs
clippy with `-D warnings`, so the call sites moved rather than being left to warn.
Likewise `set_/get_*_array_region` → `JPrimitiveArray::set_region`/`get_region`.
* `Env::get_native_interface()` is now `Env::get_raw()` — the raw pointer handed to
`ndk::NativeWindow::from_surface`. The `as *mut _` cast next to it was already commented
as bridging jni-sys skew between `jni` and `ndk`; that skew is now real (0.4 vs 0.3)
rather than hypothetical, so the comment says so.
* Return types moved from raw `jni::sys::jstring`/`jdoubleArray`/`jintArray` to
`JString`/`JDoubleArray`/`JIntArray`, because `resolve()` requires `T: Default` and raw
pointers have no `Default`. All three are `#[repr(transparent)]` over the same
`jobject`, so the exported ABI is unchanged and `Default` IS the null reference the old
code returned explicitly.
Kotlin and Gradle needed NO changes, checked rather than assumed: every affected
`external fun` in NativeBridge.kt already declares `Boolean` / `String?` / `IntArray?` /
`DoubleArray?`, which is what these signatures still present to the JVM, and the Gradle
side only shells out to cargo-ndk without naming a jni version.
Verified on NDK 30.0.14904198, both shipping ABIs, using the environment
clients/android/kit/build.gradle.kts hands cargo-ndk:
cargo clippy -p punktfunk-client-android --all-targets -- -D warnings → ok (host)
cargo test -p punktfunk-client-android → 20 passed
cargo ndk -t arm64-v8a --platform 28 clippy … -- -D warnings → ok
cargo ndk -t armeabi-v7a --platform 28 clippy … -- -D warnings → ok
cargo ndk -t arm64-v8a -t armeabi-v7a --platform 28 build → both .so LINKED
scripts/ci/check-android-jni-imports.sh … 28 → 2 ABI(s) clean at the API-28 floor
That last one matters for this change specifically: a cdylib links with dangling undefined
symbols, so the floor check is the only thing that would catch jni 0.22 hard-importing an
NDK entry point above minSdk 28 — the shape of the 0.9.0 `System.loadLibrary` regression.
It is clean.
`cargo tree -i ring` stays empty on host and on aarch64-linux-android.
|
||
|
|
93b4c725a6 |
chore(deps): x11rb 0.13 -> 0.14
Version currency for the three crates that speak core X11: pf-capture's XFixes
cursor source, pf-vdisplay's gamescope splash client, and pf-client-core's
gamescope overlay watcher. Nothing outside the workspace pulls x11rb, so all
three move together and no two versions coexist in the lock.
**The no-libxcb property survives, which is the whole reason those manifests
say `default-features = false`.** 0.14 declares no `default` feature either, so
that flag is still the belt to the braces; `libc` and `as-raw-xcb-connection`
are still optional and still reachable only through `allow-unsafe-code`, and
`dl-libxcb` still requires it too. `cargo tree -e features -i x11rb -p
pf-capture` resolves to exactly `xfixes` -> `render` + `shape` and nothing else,
and neither `as-raw-xcb-connection` nor any other libxcb-linking crate appears
in Cargo.lock. `RustConnection` remains the only connection type, so no host or
client package gains a C dependency.
**One upstream behaviour change does land**, and it is why the `SessionBind` doc
in gamescope.rs moved. 0.14 removed the abstract-unix-socket attempt from
`rust_connection::stream` -- `ConnectAddress::Socket` is now documented as
"Connect to this Unix socket by path" -- so `@/tmp/.X11-unix/X<n>` is no longer
tried ahead of the filesystem path. That doc asserted the ATTACH route's XFixes
cursor reader reached the display over the abstract socket; it now records what
is actually load-bearing. On ATTACH the session belongs to
`gamescope-session-plus`, we arm no bind, its `/tmp` is the real one, and
`punktfunk-host.service` sets no `PrivateTmp` (nor does the NixOS host unit), so
`/tmp/.X11-unix/X<n>` is exactly where `DISPLAY` says it is. The two conditions
that would have needed the abstract fallback still cannot coincide: the bind
only arms for a resolved `punktfunk-gamescope`, whose patch level 2+ makes
`SessionPlan::gamescope_cursor` false and the reader is never spawned. The
splash client is gamescope's own nested child, inside the namespace, and reads
the bound directory directly. If those ever do have to coexist the reader logs
and retries forever and the stream runs without a composited pointer -- the doc
now says so instead of promising a fallback that no longer exists.
The rest of the 0.13.2 -> 0.14.0 delta is inert here: `AtomEnum::CUT_BUFFE_Rn`
was respelled `CUT_BUFFERn` (unused), the optional `raw-window-handle` went
0.5 -> 0.6 and `libloading`'s range widened (both features off), and the MSRV
moved 1.64 -> 1.68 against a 1.96 toolchain.
Verified on .25 (Ubuntu 26.04, `CARGO_BUILD_JOBS=2`), all rc=0:
cargo build -p pf-capture -p pf-client-core -p pf-vdisplay --locked
cargo clippy -p pf-capture -p pf-client-core -p pf-vdisplay --locked -- -D warnings
cargo clippy -p pf-capture -p pf-client-core -p pf-vdisplay --all-targets --locked -- -D warnings
cargo test -p pf-capture --locked 68 passed, 0 failed
cargo test -p pf-vdisplay --locked 210 passed, 0 failed, 3 ignored
cargo check -p punktfunk-host --locked
cargo fmt --all --check
Clippy is run BOTH ways on purpose: host CI lints without `--all-targets`, so a
`#[cfg(test)]`-only import would pass the local run and fail the shipping build.
`cargo tree -i ring` stays empty.
|
||
|
|
c814340607 |
build: drop the aarch64 --cfg aes_armv8 / polyval_armv8 flags, measured obsolete
aes 0.9 runtime-detects the ARMv8-Crypto backend on aarch64 via `cpufeatures` and polyval 0.7
picks its armv8 PMULL intrinsics by target_arch, so neither cfg exists any more — passing them
is inert. That retires a real footgun rather than tidying a file: a RUSTFLAGS env var overrides
config rustflags ENTIRELY, so every aarch64 lane that set its own (cargo-ndk does so internally
for every Android arm64-v8a build) silently dropped both and ran SOFTWARE AES on the per-packet
decrypt path.
Measured before deleting, `crypto/open_in_place` (1408-byte MTU shard, AES-128-GCM, single core,
Mac15,14 M3 Ultra, four runs back to back under identical background load):
aes 0.8 + both cfgs 2.19 GiB/s
aes 0.8, cfgs stripped 225 MiB/s ~10x cliff — reproduces the recorded ~240 MiB/s
aes 0.9 + both cfgs 5.28 GiB/s
aes 0.9, cfgs stripped 5.28 GiB/s identical to 4 s.f.
The ChaCha20-Poly1305 series of the same bench was the control and moved 0.07% across the cfg
toggle at both versions, so the toggle demonstrably reached only the AES path. A final run with
the flags actually deleted (not merely RUSTFLAGS-overridden) reproduced 5.29 GiB/s.
.cargo/config.toml is kept as a tombstone carrying that table so the flags are not reintroduced.
The two CI comments that warned about losing these cfgs to a RUSTFLAGS override are updated —
mold in ci/cargo-config-mold.toml is now the only thing such an override can cost.
|
||
|
|
1fb081a1f0 |
chore(deps): move pf-console-ui from skia-safe 0.87 to 0.99
Twelve skia-safe releases (0.88 … 0.99), carrying Skia milestones 140 through 150, every one of them breaking under 0.x semver. Only three of those changes actually reach this crate — the Vulkan surface/backend-texture path, the textlayout/paragraph typography and RuntimeEffect all came through untouched: * m143 (skia-safe 0.91) DELETED SkPath's mutating API. `Path::new()` followed by `move_to`/`line_to`/`arc_to`/`close` no longer compiles at all — geometry is built through `PathBuilder` now and frozen with `snapshot()`/`detach()`. That is the entire error list: 34 E0599s over eight call sites (the hint-bar triangles and the PlayStation triangle in `glyphs.rs`, the chevron / space / backspace / check icons in `widgets.rs`, the padlock shackle in `screens/home.rs`). Each becomes a `PathBuilder` detached at the draw call, so the path is still built and thrown away once per draw exactly as before. * 0.93 deprecated the `gradient_shader` module in favour of `gradient`. Only a warning, but the Format/clippy gate runs `-D warnings`, so it is a hard break for us. The three gradients — the panel stroke in `theme.rs`, the connect-overlay vignette in `shell/overlays.rs`, the host monogram in `screens/home.rs` — now build a `gradient::Gradient` from `gradient::Colors::new_evenly_spaced` plus `Interpolation::default()`. That default (unpremul interpolation, destination colour space, shorter hue) is what the old `flags: None` argument mapped to, so the pixels do not move. The new API takes `Color4f` directly, which drops the `.to_color()` 8-bit round-trip the old signature forced. * 0.98 deprecated `vk::BackendContext::new` in favour of a builder (upstream #1292). `skia_overlay.rs` now calls `BackendContext::new_builder(...)` + `build()`, passing `max_api_version: None` so Skia keeps deriving its cap from `vkEnumerateInstanceVersion()` — bit-for-bit what `new()` passed. `build()` is the unsafe half, so the SAFETY proof moved down onto it. `ash` is untouched and stays on the workspace's exact `=0.38.0+1.3.281` pin: skia-safe lists ash only as a DEV dependency, so the bump cannot reach it. The prebuilt-binary assumption still holds — verified from the build log, not from the release page: skia-bindings printed `DOWNLOAD AND INSTALL SUCCEEDED` for `skia-binaries-a25a0fdb7d90429aa2d1-x86_64-unknown-linux-gnu-jpegd-jpege-pdf-textlayout-vulkan`, so no CI leg compiles Skia from source. The asset name DID change: `jpeg` joined skia-safe's default feature set between 0.87 and 0.99, so `jpegd-jpege` is now in the name. We take defaults, so the JPEG codecs came along — which is a fix in disguise, since `screens/library.rs` hands host poster art straight to `Image::from_encoded`, and JPEG posters used to fall out as "undecodable". The Cargo.toml comment now records the verified asset names and the silent-source- build trap for the next bump. Verified on 192.168.1.21, x86_64-unknown-linux-gnu, toolchain 1.96.0: cargo build -p pf-console-ui exit 0 cargo clippy -p pf-console-ui --all-targets -- -D warnings exit 0 cargo test -p pf-console-ui 82 passed, 1 ignored cargo fmt --all --check exit 0 |
||
|
|
2b13b6353a |
deps: move the RustCrypto wave to aes 0.9 / aes-gcm 0.11 / sha2 0.11 / hmac 0.13 / cbc 0.2 / chacha20poly1305 0.11
These six share the `crypto-common` and `digest` traits, so they move as ONE change — a
partial bump leaves crates on incompatible trait generations that cannot interoperate.
The point is to delete a footgun, not for version hygiene. `aes` 0.8 only enabled ARMv8
hardware AES on aarch64 behind `--cfg aes_armv8`, and `polyval` 0.6 gated its PMULL GHASH
path behind `--cfg polyval_armv8`. A RUSTFLAGS env var OVERRIDES config rustflags
ENTIRELY, so any aarch64 lane that sets its own (cargo-ndk does this internally for every
Android build) silently dropped both and fell back to software AES on the per-packet
decrypt path. `aes` 0.9 runtime-detects via `cpufeatures` on aarch64 and `polyval` 0.7
selects its armv8 intrinsics backend by target_arch, so neither cfg exists any more.
API changes this generation forces:
- `AeadInPlace` -> `AeadInOut`; `{encrypt,decrypt}_in_place_detached` ->
`{encrypt,decrypt}_inout_detached` taking an `InOutBuf`.
- `generic-array` -> `hybrid-array`: `Array::from_slice` is deprecated in favour of the
infallible `&[u8; N] -> &Array<u8, UN>` reference cast, or `TryFrom` for runtime slices.
- `Mac::new_from_slice` moved to `KeyInit::new_from_slice`.
- `BlockEncrypt`/`BlockDecrypt` -> `BlockCipherEncrypt`/`BlockCipherDecrypt`;
`BlockEncryptMut` -> `BlockModeEncrypt`; `encrypt_padded_vec_mut` -> `encrypt_padded_vec`.
`rsa` 0.9 is the one crate that cannot come along: it is built on `digest` 0.10 and its
0.10 line is still release-candidate only, which is not something the Moonlight pairing
ceremony should ride. Its `sha2` feature re-exports the digest its own traits speak, so the
three sites where a digest appears as an `rsa` TYPE PARAMETER (cert.rs, pairing.rs, tls.rs)
now take `rsa::sha2::Sha256` explicitly; everything else in the crate is on sha2 0.11.
The GameStream wire formats are untouched — AES-128-ECB no-padding, the CBC audio path, and
the GCM control-stream seal all keep their exact byte behaviour; only the type plumbing moved.
|
||
|
|
dfde5080cc |
chore(deps): windows-service 0.7 -> 0.8 (host + tray), removing the last windows-sys 0.52 in the tree
Version currency for the SCM plumbing behind `punktfunk-host service` (the
dispatcher, control handler and ServiceManager install) and the tray's
unprivileged QUERY_STATUS probe. No code changed in either crate.
The payoff is dependency unification, not the API. `windows-service 0.7` was the
ONLY crate in the workspace still pulling `windows-sys 0.52`, so it alone kept a
fourth windows-sys major compiling. It resolves to 0.8.1, which moves to
`windows-sys 0.61` — a version the tree already builds — and the duplicate
disappears:
cargo tree -d --target x86_64-pc-windows-msvc | grep '^windows-sys v'
before: 0.45.0, 0.52.0, 0.59.0, 0.61.2
after: 0.45.0, 0.59.0, 0.61.2
Note 0.8.0 would NOT have been enough — it lands on windows-sys 0.59. 0.8.1 is
the release that reaches 0.61, hence the `"0.8"` caret plus the comment pinning
the reasoning to the manifest.
The 0.7 -> 0.8 delta is tiny and touches nothing this tree calls: `ServiceAccess`
gains READ_CONTROL / WRITE_DAC / WRITE_OWNER (additive), and `Service::raw_handle`
changes return type from `Security::SC_HANDLE` to `Services::SC_HANDLE` as a
consequence of the windows-sys bump — we never call it. `ScHandle` is crate-private
upstream. No enum gained variants, and the service control handler's match already
ends in a `_ =>` arm, so the `#[non_exhaustive]` types stay safe.
What remains duplicated (deliberately out of scope here): windows-sys 0.45 via
`jni`, and 0.59 via `punktfunk-core` + `if-addrs`.
|
||
|
|
00245499e0 |
chore(deps): android_logger 0.14 → 0.15
Version currency for the Android client's only `log` backend. No code change: 0.15 is almost entirely an internal refactor (the single `lib.rs` split into `config`/`arrays`/ `id`/`platform_log_writer`/`tests`), and the surface this crate uses — `init_once`, `Config::default`, `with_max_level`, `with_tag` — is untouched. The lockfile delta is the version and checksum alone: no dependency was added, removed or re-resolved, and the third-party crate count stays at 582. The one thing 0.15 adds that we must NOT take is recorded next to the dependency: the new opt-in `android-api-30` feature filters levels through `__android_log_is_loggable_len` so logcat's `setprop log.tag.*` overrides are honoured, but it HARD-LINKS that API-30 symbol. Against our minSdk-28 floor that is a `System.loadLibrary` failure on Android 9/10 — the identical shape of the ndk 0.9.0 `AMediaCodec_setOnFrameRenderedCallback` break the manifest already warns about a few lines further down. Default features keep it off; the comment explains why so nobody "completes" the upgrade by enabling it. Verified with cargo-ndk (NDK 30.0.14904198), which is the only way to exercise this crate at all — `android_logger` sits behind `cfg(target_os = "android")`, so the host workspace build never compiles it: cargo ndk -t arm64-v8a check -p punktfunk-client-android → ok cargo ndk -t armeabi-v7a check -p punktfunk-client-android → ok Checked, not built: these are `cargo check` runs, not a linked `.so` and not an APK. |
||
|
|
94e3629905 |
chore(deps): wasapi 0.23 -> 0.24 (Windows audio), and correct the five comments that still describe its fixed GetDevice bug
Version currency for the crate behind the host's WASAPI loopback capture and virtual mic, and the Windows client's render/capture path. No behavior change. The 0.23 -> 0.24 API delta is almost entirely additive (device-change notification callbacks, `AudioMeterInformation`, `HardwareSupport`, `DeviceState: Clone + Copy`). The single removal is `AudioClient::get_bufferframecount`, deprecated since 0.17 in favour of `get_buffer_size` — this tree never called it, so no call site moved. 0.24 also fixes upstream the dangling-`PCWSTR` bug this tree routes around in five places: `DeviceEnumerator::get_device` used to build its argument as `PCWSTR::from_raw(HSTRING::from(id).as_ptr())`, dropping the `HSTRING` at the end of that statement so `GetDevice` read freed memory. Those five comments asserted the bug in the PRESENT tense and are now wrong, so they are corrected here rather than left to mislead. The workarounds themselves STAY: `open_wasapi_device` is still the one resolution path whose errors name the endpoint id and whose `IMMDevice` `probe_activation` needs, and `device_by_id` additionally filters to ACTIVE endpoints (`EnumAudioEndpoints(dir, DEVICE_STATE_ACTIVE)`), which the crate's `get_device` does not. Removing them is a behavior change, not currency. ⚠ This does NOT collapse the duplicate windows-rs. wasapi 0.24 still depends on `windows ^0.62` / `windows-core ^0.62` exactly as 0.23 did, so the crates.io `windows 0.62.2` still sits alongside the pinned git copy that `clients/windows` uses. That duplicate costs build time and binary size, not correctness, and the blanket `[patch.crates-io] windows` that would collapse it stays ruled out — the pinned rev uses header-named features while a dozen manifests still use the old `Win32_*` namespace features. |
||
|
|
2d037aa443 |
test(gamestream): cover the TLS 1.2 Moonlight handshake and pin the post-quantum group
PR #192 moved the rustls backend to aws-lc-rs and merged before CI reported. Two of the things it changed here shipped with no assertion behind them. `generate()` mints the RSA-2048 host identity and runs ONLY when no cert exists, so no upgraded box ever re-executes it — a fresh install is the only thing that would have found a regression. It was reached by other tests via `ServerIdentity::ephemeral()`, but purely as a fixture: nothing checked that what came back was still RSA-2048, which is the one property Moonlight requires. The handshake behaviour had no coverage at all, and the GameStream TLS path is the single place a legacy peer meets the new backend. Three tests: - generate_mints_a_loadable_rsa2048_identity — the fresh-install path, asserting the cert signature is 256 bytes (RSA-2048) rather than depending on an `rsa` accessor that could change shape. - moonlight_shaped_peer_completes_a_tls12_mutual_handshake — a peer that pins out of band, as Moonlight does, presenting an RSA-2048 client cert against the real `tls::server_config`. - tls13_negotiates_the_post_quantum_group — pins X25519MLKEM768 by name, so a provider or feature regression that silently drops ML-KEM back to a classical curve fails here instead of in the field. Also corrects the comment on `generate()`. It opened by asserting the workspace is ring-only because aws-lc-sys breaks Windows CI, and explained that rcgen's *ring* backend is what loads the RSA key. Both are now false: rcgen is on aws_lc_rs and loads and self-signs the key fine — verified, not assumed. rcgen still cannot GENERATE an RSA key on either backend, which is the part of the comment that remains true and load-bearing. Verified on Linux (Ubuntu 26.04, x86_64): 3/3 pass, clippy clean both with and without --all-targets (host CI lints without it), and the native-only `--no-default-features --features pyrowave` build still checks clean — the whole module is gamestream-gated, so it compiles out there. |
||
|
|
c95db8eebc |
Merge pull request 'Move TLS to aws-lc-rs with post-quantum key exchange, drop ring via ureq 3, and fix the dependency defects behind it' (#192) from worktree-aws-lc-rs-migration into main
apple / swift (push) Successful in 2m18s
audit / bun-audit (plugin-kit) (push) Successful in 20s
audit / bun-audit (web) (push) Successful in 14s
audit / docs-site-audit (push) Successful in 16s
audit / pnpm-audit (push) Successful in 12s
audit / cargo-audit (push) Successful in 2m44s
audit / bun-audit (sdk) (push) Successful in 1m33s
audit / license-gate (push) Successful in 5m13s
ci / rust (push) Failing after 1m48s
ci / web (push) Successful in 1m45s
audit / miri (push) Successful in 10m5s
ci / docs-site (push) Successful in 1m29s
audit / c-abi-asan (push) Successful in 10m24s
ci / bun-nix (push) Successful in 1m6s
apple / distribute (push) Successful in 14m0s
deb / build-publish-gamescope (push) Failing after 56s
windows-drivers / driver-build (push) Successful in 1m59s
android / android (push) Successful in 19m12s
arch / build-publish (push) Successful in 19m57s
windows-drivers / probe-and-proto (push) Successful in 25s
ci / rust-arm64 (push) Successful in 13m8s
apple / screenshots (push) Successful in 7m34s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 2m14s
deb / build-publish (push) Successful in 10m28s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Successful in 10s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 7m38s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 2m52s
deb / build-publish-client-arm64 (push) Successful in 12m9s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 7m56s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4m49s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 1m29s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4m27s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 3m12s
deb / build-publish-host (push) Successful in 19m29s
docker / deploy-docs (push) Failing after 1m58s
docker / builders-arm64cross (push) Successful in 6m28s
deb / smoke-install (push) Failing after 4m16s
flatpak / build-publish (push) Successful in 12m18s
nix / flake (push) Failing after 20m59s
windows-host / package (push) Successful in 19m52s
windows-host / winget-source (push) Skipped
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 7m36s
windows-host / canary-manifest (push) Successful in 27s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 9m53s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 22m36s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 2m50s
Reviewed-on: #192 |
||
|
|
6202543b21 |
Merge pull request 'ci: cache the C/C++ half, link with mold, fix the debug/release cache collision, consolidate the Apple and Windows-client workflows' (#191) from worktree-ci-optimization into main
android / android (push) Canceled after 34s
apple / swift (push) Canceled after 1m49s
apple / distribute (push) Canceled after 0s
apple / screenshots (push) Canceled after 0s
arch / build-publish (push) Canceled after 0s
ci / rust (push) Canceled after 0s
ci / rust-arm64 (push) Canceled after 55s
ci / web (push) Canceled after 49s
ci / docs-site (push) Canceled after 0s
ci / bun-nix (push) Canceled after 42s
deb / build-publish (push) Canceled after 15s
deb / build-publish-host (push) Canceled after 0s
deb / build-publish-gamescope (push) Canceled after 0s
deb / build-publish-client-arm64 (push) Canceled after 0s
deb / smoke-install (push) Canceled after 0s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Canceled after 0s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Canceled after 0s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Canceled after 0s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Canceled after 0s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Canceled after 0s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Canceled after 0s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Canceled after 0s
docker / builders-arm64cross (push) Canceled after 0s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Canceled after 0s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 0s
docker / deploy-docs (push) Canceled after 0s
flatpak / build-publish (push) Canceled after 0s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 0s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 0s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Canceled after 0s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (push) Canceled after 0s
windows-drivers / probe-and-proto (push) Canceled after 0s
windows-drivers / driver-build (push) Canceled after 0s
windows-host / package (push) Canceled after 0s
windows-host / canary-manifest (push) Canceled after 0s
windows-host / winget-source (push) Canceled after 0s
decky / build-publish (push) Successful in 1m23s
Reviewed-on: #191 |
||
|
|
d0a7b262d2 |
chore(deps): regenerate notices + make audit.yml's header match what it now scans
windows-drivers / driver-build (pull_request) Successful in 1m57s
windows-drivers / probe-and-proto (pull_request) Successful in 35s
apple / swift (pull_request) Successful in 2m29s
apple / screenshots (pull_request) Skipped
ci / bun-nix (pull_request) Successful in 52s
ci / rust-arm64 (pull_request) Failing after 3m22s
ci / web (pull_request) Successful in 3m47s
ci / docs-site (pull_request) Successful in 5m10s
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 7m21s
windows / build (x86_64-pc-windows-msvc) (pull_request) Failing after 24s
ci / rust (pull_request) Failing after 11m30s
nix / flake (pull_request) Failing after 30m26s
android / android (pull_request) Successful in 13m2s
THIRD-PARTY-NOTICES regenerated after the dependency changes (582 crates). audit.yml's header claimed to cover "EVERY dependency tree the project ships"; it now actually does, so the note spells out that each Rust lockfile needs its own `--file` — a bare `cargo audit` reads only the root one, which is how the drivers lock stayed unscanned while already sitting in this job's `paths:` filter. Also corrected "BOTH Rust workspaces" for the licence gate, which covers the host + driver workspaces. Both cargo-about legs re-run after the dependency removals: RC=0. |
||
|
|
51a005dd43 |
fix(deps): close the audit gaps, drop unused declarations, declare what is used
Acting on the 2026-08-13 dependency sweep. Every claim below was re-verified against
the tree before acting on it (greps carry a positive control; the advisories were
re-checked with cargo audit 0.22.2).
SECURITY
- event-listener 5.4.1 -> 5.4.2 (RUSTSEC-2026-0221, unsound Send/Sync on StackSlot;
reaches the tray via zbus and the host via ashpd). This sat unnoticed because
`cargo audit` reports unsoundness as a WARNING and the job fails only on
vulnerabilities — audit.toml now says so out loud.
- spin 0.9.8 -> 0.9.9. 0.9.8 is YANKED and was genuinely compiled (flume via mdns-sd
and relm4, plus lazy_static).
- wayland-scanner 0.31.10 -> 0.31.11, which moves quick-xml 0.39 -> 0.41. That is the
exact trigger audit.toml documented for RUSTSEC-2026-0194/0195, so both ignores are
deleted rather than left as permanent exceptions. Only RUSTSEC-2023-0071 (rsa
Marvin, still unfixed upstream) remains.
- Corrected audit.toml's claim that `paste` arrives "via utoipa-axum": rav1d pulls it
too, so every client has it through the decode path and dropping utoipa-axum would
not have cleared it.
TWO CI GATES THAT SCANNED NOTHING
- `cargo audit` only ever reads the ROOT Cargo.lock. The drivers lock was already in
this job's `paths:` filter, so edits to it triggered a run that then ignored them.
All four secondary workspaces now get an explicit `--file` (verified: clean, bar the
known `paste` warning in drivers).
- packaging/windows/pf-vkhdr-layer had NO lockfile at all while shipping as a DLL in
the host installer, so every build resolved fresh and neither cargo-audit nor
cargo-about ever saw it. Lockfile generated and committed, and added to `paths:`.
UNUSED / DUPLICATE DECLARATIONS
- punktfunk-host: removed 13 dependencies it never references — the Wayland stack
(client, protocols{,-wlr,-misc}, scanner, backend), xkbcommon, reis, khronos-egl,
ash, usbip-sim, parking_lot, bytemuck. The code moved to pf-inject and pf-zerocopy
in the subsystem extraction and those crates declare them; only the manifest entries
and their now-false comments stayed. Also dropped four redundant re-declarations
(tokio/serde_json/futures-util in the Linux block, tower in dev-deps).
- Removed genuinely unused: bytes (punktfunk-core), anyhow (pf-win-display),
tracing (clients/cli), anyhow (clients/session), serde (clients/windows).
- Removed the high-level `wdk` crate from all five driver crates and the drivers
workspace: none of them ever referenced `wdk::` (62 `wdk_sys::` uses; pf-umdf-util
is a full WDF crate that never declared it). `tracing`/`tracing-subscriber` remain
in that lock afterwards but ONLY as wdk-sys build-dependencies, not in the DLLs.
- pf-win-display took punktfunk-core with `quic` for one type (`Mode`) that lives in
the ungated `config` module; now `default-features = false`, which keeps
quinn/tokio/rcgen/opus out of a leaf crate's declared closure.
- pf-encode declared the windows-rs feature `Wdk_Graphics_Direct3D` for a call that
lives in pf-frame and is resolved via GetProcAddress on gdi32.
LATENT BREAKAGE (compiled only by feature unification)
- pf-inject uses `tokio::select!` without declaring `macros` (borrowed from
punktfunk-core's quic feature); pf-capture uses `tokio::sync::oneshot` without
declaring `sync` (borrowed from ashpd->zbus); pf-client-core uses the `minwindef`
and `winnt` windows-rs headers without declaring them (borrowed from
clients/windows). Each now declares what it uses, so an unrelated crate changing its
features cannot break them.
- pf-console-ui took pf-client-core WITHOUT `default-features = false`, unlike every
other consumer. That default is `pyrowave`, which compiles the vendored PyroWave C++
— "fatal on Windows ARM64". Only safe today because the ARM64 leg passes
--no-default-features (which also drops `ui`).
CORRECTED A FALSE INVARIANT
- clients/windows claimed "the workspace builds ONE windows-rs". It does not: wasapi
pulls the crates.io windows 0.62.2 beside the git-rev copy. The invariant that DOES
hold is narrower (reactor and that crate share one rev, which is what makes the
IDXGISwapChain1 hand-off type-check). Comment rewritten, with a warning against
"fixing" it via a blanket [patch.crates-io] — this rev uses header-named features
while a dozen other manifests use the old Win32_* namespace ones.
Plus the safe in-compat `cargo update` sweep (no manifest edits).
Verified on macOS: punktfunk-core 385, pf-update-check 32, c_abi 1 (with
LIBRARY_PATH=/opt/homebrew/opt/opus/lib), cargo audit clean bar the two known
unmaintained warnings. Linux and Windows legs follow.
|
||
|
|
b84d37b5a0 |
test(host): make two socket stubs survive ureq 3 / Windows
Both failures found running the store + plugin-launch tests on the Windows runner after the ureq 3 port. Neither is a production defect — the request/response round trip and the 304 semantics both hold — but both tests were resting on assumptions that ureq 2 happened to tolerate. catalog::ureq_returns_304_as_ok: the stub answered without ever reading the request. Closing a socket that still holds unread received data makes Windows send an RST rather than a FIN, which discards the response already written, so the client saw a transport error (os error 10053) instead of the 304 the test exists to pin. The stub now drains the request first. The pinned behaviour is unchanged and still true: ureq 3 turns only `is_client_error() || is_server_error()` into Err, so 304 arrives as Ok exactly as before. plugin_launch::asks_the_registered_plugin_and_takes_its_answer: hardcoded a cwd of `/opt/emu`, which has no drive letter and is therefore NOT `Path::is_absolute` on Windows, so `validate_reply` refused the recipe. This test could never have passed on Windows, with either ureq version — its sibling `a_working_directory_must_be_absolute` already had the `cfg!(windows)` split and this one was simply missed. Confirmed by diagnostic before touching it: the body came back over ureq 3 byte-perfect, so everything up to validation was working. |
||
|
|
9ec8350fc3 |
chore(licenses): retire ring's licence exception now that ring is gone
`about.toml` carried `OpenSSL` in the global accepted list and a `[ring]` per-crate acceptance, both there solely because ring's licence is an AND that includes the OpenSSL terms. The ureq 2 -> 3 upgrade removed ring from every target we build, and aws-lc-sys 0.44's SPDX (ISC AND (Apache-2.0 OR ISC) AND Apache-2.0 AND MIT AND BSD-3-Clause AND ... MIT-0) carries no OpenSSL clause, so neither entry has anything left to permit. Note about.toml sets no `targets`, so cargo-about still walks quinn-proto's wasm-only ring edge — removing the exception is safe not because ring is invisible but because ring 0.17.14 declares `Apache-2.0 AND ISC`, and both are globally accepted already. Verified by running the gate itself, both legs of what audit.yml runs: cargo about generate about.hbs --fail -> 0 cargo about generate -m packaging/windows/drivers/Cargo.toml -c ... -> 0 and proved non-vacuous with a negative control: dropping "ISC" from the accepted list makes the first leg exit 1. THIRD-PARTY-NOTICES regenerated: 601 -> 580 crates (ureq 3 pulls a smaller tree than ureq 2 + ring), now listing ureq 3.4.0. |
||
|
|
3ccfd01699 |
feat(deps): upgrade ureq 2 -> 3, removing ring from the tree entirely
The aws-lc-rs move left `ring` compiled in for one reason: ureq 2 names `features = ["ring", ...]` inside its own `[dependencies.rustls]` block, and cargo features are additive, so no dependent could switch it off. ureq 3 declares rustls with `default-features = false` and selects no backend, which finally makes the choice ours. `cargo tree -i ring` is now empty for macOS, Windows and Linux. The one remaining hit under `--target all` is quinn-proto's wasm-only dependency (`cfg(all(target_family = "wasm", target_os = "unknown"))`), a target we never build. ⚠ The dependency must be spelled `features = ["rustls-no-provider", "rustls-webpki-roots"]`. ureq 3's convenience `rustls` feature expands to include `_ring` — the same shape of trap as rustls's own `features = ["ring"]`, and the reason punktfunk-webos still carries both backends today. Ported 9 files. The two pinning call sites (the desktop client's library fetch and the tray's status poll) needed a custom ureq Connector, because ureq 3's `TlsConfig` exposes roots/client-cert/off-switch but no hook for a custom ServerCertVerifier. That glue lives once in punktfunk-core behind a new off-by-default `ureq-tls` feature rather than being hand-rolled twice on a trust boundary; the Apple/Android cdylib embedders do not enable it and pull no HTTP stack. The connector is modelled on ureq's own crate-private RustlsConnector and is transport glue only. Two behaviour changes worth noting, both improvements: - Body caps are enforced by the reader, so an over-cap response is now an Err rather than ureq 2's silent truncation — which used to surface as a signature failure pointing at the wrong thing. - A pin mismatch matches ureq 3's typed `Error::Rustls(..)` instead of sniffing a substring out of a transport message, which could also fire on unrelated cert errors. Conditional requests are unchanged: 304 still arrives as Ok (only 4xx/5xx are Err), which the existing `ureq_returns_304_as_ok` socket test still pins. Also removed four now-dead `std::io::Read` imports. One of them (plugin_launch) is still needed by its test module, so it moved there rather than being deleted: host CI lints without `--all-targets`, so a top-level import used only under cfg(test) fails the shipping build. Verified on macOS: punktfunk-core (quic + ureq-tls) checks clean, pf-update-check 32/32, cargo fmt clean. |
||
|
|
79d755cd98 |
feat(crypto): move the rustls backend from ring to aws-lc-rs, with PQ key exchange
The workspace pinned `ring` everywhere because aws-lc-sys 0.41.0 failed to C-compile on the Windows CI runner. Re-tested on that runner (.133) with aws-lc-sys 0.44.0: the `params.c` cl.exe failure does not reproduce under MSVC 14.44, and rustls's `aws_lc_rs` feature turns on `aws-lc-rs/prebuilt-nasm`, so no NASM is needed on the box either. That unblocks post-quantum TLS: `prefer-post-quantum` offers X25519MLKEM768 first on every TLS 1.3 handshake (mgmt API, native control plane, QUIC), which ring cannot do — it has no ML-KEM. Classical curves stay in the list, so older clients still connect. rustls, quinn, rcgen and tokio-rustls each select a backend independently, so all four had to move together; a single dissenter pulls a second crypto stack in via feature unification. The direct `ring` users (ed25519 in pf-update-check, SHA-256 in the Windows updater) moved to aws-lc-rs, whose API is ring-compatible. `ring` does NOT leave the tree: ureq 2 names `features = ["ring"]` in its own rustls dependency line and cargo features are additive, so no dependent can switch it off. Two backends compiled in means rustls refuses to infer one, and anything built via `ClientConfig::builder()` panics instead of picking — which is what ureq's default agent does on its first HTTPS request. `tls::install_default_provider()` makes the choice explicit; it runs at each binary's entry point and defensively in pf-client-core, which several binaries link. Dropping ring entirely needs the ureq 2 -> 3 upgrade (36 call sites), deliberately left out of this change. Verified on macOS: pf-update-check 32, punktfunk-core 385, c_abi 1 (the last with LIBRARY_PATH=/opt/homebrew/opt/opus/lib) — aws-lc-sys links into the C ABI harness, so the Swift/Kotlin embedders keep working. cargo fmt --all --check clean. |
||
|
|
5fbf04f56d |
Ship punktfunk-gamescope on apt, support Debian 13, and state the real host floor (#190)
ci / docs-site (push) Successful in 1m19s
windows-host / package (push) Failing after 55s
ci / rust-arm64 (push) Successful in 1m40s
windows-host / canary-manifest (push) Skipped
windows-host / winget-source (push) Skipped
ci / bun-nix (push) Successful in 20s
apple / swift (push) Successful in 1m39s
deb / build-publish-gamescope (push) Failing after 2s
android / android (push) Successful in 6m22s
deb / build-publish-host (push) Successful in 4m38s
deb / build-publish (push) Successful in 5m31s
ci / web (push) Successful in 7m54s
apple / screenshots (push) Successful in 5m57s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 3m30s
deb / build-publish-client-arm64 (push) Successful in 8m26s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 6m4s
docker / builders (ci/gamescope-trixie.Dockerfile, punktfunk-gamescope-trixie) (push) Successful in 1m45s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 5m41s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m27s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 3m19s
decky / build-publish (push) Successful in 51s
arch / build-publish (push) Successful in 10m45s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10m24s
ci / rust (push) Canceled after 6m35s
deb / smoke-install (push) Canceled after 2m50s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Canceled after 2m34s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Canceled after 1m2s
docker / builders-arm64cross (push) Canceled after 0s
docker / deploy-docs (push) Canceled after 0s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 1m33s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 6m22s
|
||
|
|
85980b425e |
docs: state the real host floor — Ubuntu 26.04+ / Debian 13+ — and name Debian everywhere
ci / docs-site (pull_request) Successful in 1m17s
ci / rust-arm64 (pull_request) Successful in 1m29s
ci / bun-nix (pull_request) Successful in 1m33s
apple / swift (pull_request) Successful in 1m44s
apple / screenshots (pull_request) Skipped
ci / web (pull_request) Successful in 3m56s
android / android (pull_request) Successful in 9m55s
ci / rust (pull_request) Successful in 15m59s
The floor that matters is the DESKTOP, not the package: 24.04 installs punktfunk-host and then has no compositor over the version floors and no gamescope, which reads as a bug rather than an unsupported base. The requirements page now leads with a per-release table separating 'package installs' from 'can actually host', and install.md carries the same caveat next to the apt row. Debian was already a supported target after the previous commits but was still invisible at the entry points — README's install table, the docs index cards, and the 'what you need' list all said Ubuntu only. All three now name Debian and carry the version floor. |
||
|
|
107fa3472d |
docs: Linux Mint 22.x cannot host, and 24.04 gives the host no compositor
Measured on a real linuxmintd/mint22-amd64 image and on Ubuntu 24.04. The
package installs on both, which is exactly what makes this easy to miss —
nothing on the box can then produce a stream:
* Cinnamon cannot host a virtual display (Muffin has no RecordVirtual).
* gamescope is absent from 24.04 and cannot be built for it: the tree needs
wayland >= 1.23.1 (has 1.22.0), libinput >= 1.26 (1.25), libavif >= 1.2.1
(1.0.4), pixman >= 0.44 (0.42), plus libdisplay-info2 and libxcb-errors0,
neither of which 24.04 packages at all.
* Switching desktop does not rescue it — 24.04 has KWin 5.27 (floor 6.5.6)
and GNOME Shell 46 (floor 48). Only sway 1.9 is even a candidate.
So the gamescope route documented for Cinnamon holds for LMDE 7 (Debian 13,
verified end to end) but NOT for Linux Mint 22.x — which is every mainstream
Mint until Mint 23 lands on a 26.04 base in December 2026. Both the Debian and
Ubuntu pages now say so, and the Debian page carries a per-edition table.
Also states what Debian 13 itself can drive: GNOME 48.7 and sway 1.10 are above
the floors; its KWin 6.3.6 is below.
|
||
|
|
0bfc7fe913 |
ci: fold release.yml into apple.yml and the two Windows client workflows into one
apple / swift (pull_request) Successful in 1m43s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
windows-drivers / probe-and-proto (pull_request) Successful in 30s
windows-drivers / driver-build (pull_request) Successful in 1m49s
ci / docs-site (pull_request) Successful in 1m21s
ci / bun-nix (pull_request) Successful in 31s
ci / web (pull_request) Successful in 3m50s
ci / rust-arm64 (pull_request) Successful in 8m32s
android / android (pull_request) Successful in 7m22s
ci / rust (pull_request) Successful in 14m7s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 3m6s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 8m7s
Two merges, both of which exist to express an ordering Gitea cannot express across files, and both of which delete a duplicated build. release.yml -> apple.yml (as the `distribute` job) The name described neither what it did (Apple only — every other platform's release is its own packaging workflow attaching to the same Gitea release on a v* tag, with announce.yml as the manual "go") nor anything a reader would guess. The name was the smaller problem. Gitea has no cross-workflow `needs`, so nothing sequenced it against apple.yml's tests: a canary main push uploaded iOS, macOS and tvOS builds to TestFlight even when `swift test` had just failed on that same commit. It is now `needs: swift`, which is only expressible in one file. The two files' paths: filters had also drifted — apple.yml watched crates/**, release.yml watched crates/punktfunk-core/**. The merged filter takes the NARROW one, because that is the correct one: everything on this runner is built from punktfunk-core via build-xcframework.sh, and punktfunk-core's only path dependency is its own vendored fec-rs. That is checkable in one command, and the header says so, and says to widen it if that ever stops being true. Net effect on the shared mac mini: pushes that touch host-side crates no longer build or upload anything Apple. windows.yml + windows-msix.yml -> windows-client.yml The pair built the same three crates FOUR times per client push on ONE runner: debug x64 + arm64 for lint/test, release x64 + arm64 for packaging. windows-host.yml already records why a second (debug) dep tree on this machine is a liability rather than a cost — it re-runs openh264-sys2's vendored C++ through cc-rs's cl.exe fan-out and tips the runner into C1069, which is disk exhaustion wearing a compiler error's clothes. So there is one release build per arch now and clippy/fmt/test run against it, exactly as windows-host.yml does. The paths list went from three copies to one; PRs get the build/lint/test signal and stop before packaging. The rename is safe, and this is worth recording because the GitHub instinct is wrong here: `github.run_number` is REPO-WIDE in Gitea, not per-workflow — consecutive runs of DIFFERENT workflows get consecutive numbers (verified against the API: android 13226, apple 13227, arch 13228, ci 13229, deb 13230). The canary MSIX version <minor>.<run>.0 and Apple's CURRENT_PROJECT_VERSION therefore keep climbing across a rename. On GitHub the same rename would reset both to 1, sorting every new canary below the published ones and getting the TestFlight uploads rejected outright. 25 workflows, down from 27, and every `name:` now matches its filename. Cross-references in windows-host.yml, windows-drivers.yml, android.yml, flatpak.yml, sbom.yml, the provisioning scripts, gitea-release.sh and clients/windows/packaging/README.md updated. |
||
|
|
3f7fbf1061 |
ci: build the web console once per push instead of once per packaging job
The Nitro console bundle is a pure function of web/ and sdk/, and it was being built
six times on every push: ci.yml, deb, both RPM legs (f43 + f44), arch, and the docker
app image, at roughly 2.5 min each. windows-host.yml has cached it on exactly this
shape for a while — this extends the same arrangement to the Linux packaging legs,
sharing one key family so whichever job builds it first warms the others.
The bun version is part of the key. Each builder image runs the bun.sh installer at
image-build time, so rust-ci, fedora-rpm and arch-ci can drift apart; keying on it
means they share while they agree and simply stop sharing when they do not, rather
than one image's bun silently producing the bundle another image ships.
Each packaging path needed a different hand-off:
* deb — build-web-deb.sh already builds only if web/.output is missing, so the
restore alone is enough; the workflow's build+smoke step is now gated on
the miss.
* arch — makepkg builds with PF_SRCDIR pointing at the workspace, so a restored
bundle is already where it needs to be. PKGBUILD gains the same
build-if-missing guard the deb script has.
* rpm — neither direction works by default. build-rpm.sh packages a `git archive`
tarball and web/.output is gitignored, so a bundle in the workspace is
invisible to rpmbuild; and the spec's own build lands in rpmbuild's
%{_topdir}, which build-rpm.sh mktemps and removes on EXIT, so a console
built there is gone before the cache's post step and the cache would never
populate — every run a miss that quietly rebuilt. So the workflow builds it,
and hands it over by absolute path through a new optional `pf_prebuilt_web`
macro. Undefined (plain rpmbuild, COPR) takes the original build path.
Every path asserts the bundle exists and carries the Bun.serve marker, on cache hits
too. A cache is one more place a wrong artifact can come from, and the packaging
scripts' build-if-missing behaviour — correct for a local build — would otherwise turn
a broken restore into either a silent rebuild or, with the build step skipped, a
package with no console in it. That is not hypothetical: windows-host.yml shipped
0.22.1 and 0.22.2 with no console because an unset path variable was handled by a
single Write-Host, which is why its equivalent step throws.
|
||
|
|
f1dc6c9f94 |
ci: cache the C/C++ half, link with mold, and split the debug/release target caches
Three independent reasons Rust CI stayed slow despite sccache, fixed together because
they share the same measurement.
1. sccache only ever covered RUSTC. Every C/C++ dependency in the tree — aws-lc-sys,
openh264-sys2's vendored C++, the CMake-built libopus behind audiopus_sys — was
compiled from scratch on every job of every workflow. CMAKE_{C,CXX}_COMPILER_LAUNCHER
plus CC_/CXX_x86_64_unknown_linux_gnu route both build-script styles (cc-rs and
cmake-rs) through the same shared cache.
The CC_* vars are JOB-scoped in ci.yml and deb.yml, never workflow-scoped: the
arm64 cross image sets its own CC_x86_64_unknown_linux_gnu=pf-host-cc, the wrapper
that keeps ffmpeg-sys-next's host probe off the arm64 include dirs. Overwriting it
would surface as a header mismatch rather than as a CI config error.
2. Linking is cacheable by nothing, and these jobs relink the host, client, session,
cli, worker and tray on every run — twice per push for rpm (f43 + f44). The four
Linux builder images now install mold and carry a $CARGO_HOME/config.toml that uses
it for x86_64. aarch64 is deliberately left alone (cross driver, already-fast legs).
Each image asserts `mold --version` in its build, so an image can never ship the
flag without the linker: docker.yml goes red and :latest stays on the last good one.
3. THE EXPENSIVE ONE. ci.yml (debug) and deb.yml (release) named a byte-identical
target-cache key, under a comment claiming the release build reused ci.yml's
artifacts. It never could. actions/cache is first-saver-wins on an exact key and
ci.yml is the faster job, so the shared key always held a debug-only target/ — and,
worse, deb.yml could then never save its own, because the key was taken. Every
canary .deb has been a from-scratch release build for as long as both keys existed.
Same collision on the arm64 pair, and a third participant in
linux-client-screenshots.yml. Split into -debug-/-release- key families; that job
reads deb's tree via restore-keys but keeps its own exact key so it can never win
the save race and replace a full tree with its single-crate one.
Also: one scripts/ci/ensure-sccache.sh replaces ten copy-pasted bootstrap blocks that
had already drifted into two dialects (GNU tar --wildcards vs bsdtar), every Rust job
now ends with --show-stats so a cache regression is visible instead of just "CI got
slower", and deb.yml's web install joins every other CI install on --ignore-scripts.
No behaviour change to any artifact: same compilers, same flags, same outputs.
|
||
|
|
5d8682d7b7 |
feat(vdisplay): explain a cinnamon/muffin compositor pin instead of listing backends
PUNKTFUNK_COMPOSITOR=cinnamon is the first thing a Mint or LMDE user reaches for, and the bare list of accepted values invites the next-closest guess — 'mutter', since Muffin is a Mutter fork — which starts a session that fails deep inside an org.gnome.Mutter.ScreenCast call Muffin does not serve. No value of the variable can work, so say that and name headless gamescope, which needs no desktop compositor. |
||
|
|
030bc8a1c2 |
docs(debian): use deb822 sources for non-free, not apt-add-repository
software-properties-common is not available in Debian 13, so the apt-add-repository line could not have worked. Debian 13 keeps its sources in deb822 format; edit Components there instead (verified in a trixie container — the NVIDIA driver it then offers is 550, above our 535 floor). |