Commit Graph
183 Commits
Author SHA1 Message Date
lucannez64 fdc579c2e6 Merge remote-tracking branch 'origin/main' into fix/mic-input 2026-10-19 00:55:17 +02:00
lucannez64andClaude Opus 5.5 74723556ef AUHAL: accept Vivox's playback format and trace recorded levels
The issue #75 trace shows recording now runs, but Vivox's playback unit
(mic test loopback, other players' voices) sets interleaved Float32 stereo
at 32 kHz on input scope element 0 and got -10868. Apply the relaxed rule
to both client sides (input scope element 0, output scope element 1); the
playback path already interleaves for the device and PulseAudio resamples.

AudioUnitRender(bus 1) now traces frames and peak level (no samples) so a
log shows whether the client pulls sound or silence. The input check also
sets Vivox's playback format and expects unsigned 16-bit to be refused.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:41:10 +02:00
lucannez64andClaude Opus 5.5 d525aba5f6 AUHAL: only accept float or signed integer recording formats
RenderBus pads missing frames with zeros, which is loud for unsigned PCM
(silence is 0x80 for 8-bit, 0x8000 for 16-bit). Reject unsigned and 8-bit
formats on element 1; voice engines use float or signed 16-bit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:25:23 +02:00
Kalah 32ed82e9f2 Merge pull request #79 from lucannez64/fix/replace-shared-identity
Provision a platform identity on setup and replace the shared serial/UUID on update
2026-10-19 00:22:48 +02:00
lucannez64andClaude Opus 5.5 c068e32152 install-runtime.sh: provision a platform identity for new prefixes
When install-runtime.sh creates the prefix (first-time setup, regular or
Nix), it now runs configure-darling-platform.py --provision --write once
the runtime is stopped, so each new install gets its own synthetic serial,
MLB, UUID and ROM. A prefix counts as new the same way Darling decides it:
the directory did not exist before the first `darling shell`. Existing
prefixes keep their identity on reinstall and update.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:22:07 +02:00
lucannez64andClaude Opus 5.5 fd8732d4bc update.sh: replace the shared serial and UUID automatically
Older setups shipped serial C02ZL0GVMD6N and UUID
6F3B2A1E-8C4D-4E5F-9A7B-1D2C3E4F5A6B to every install. After installing,
update.sh now runs configure-darling-platform.py --replace-known-defaults,
which provisions the prefix only when its saved identity still has one of
those values. Other custom values (imported serials/UUIDs, model, board,
manufacturer, ROM, MLB) are kept; prefixes with no saved identity or only
custom values are not touched.

provision() also drops a standalone system-id or provisioning_UDID derived
from the shared UUID instead of keeping it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:17:22 +02:00
lucannez64andClaude Opus 5.5 f8b875ddf1 AUHAL: accept interleaved recording formats on element 1
Vivox sets interleaved Float32 stereo on output scope element 1 and
AUBase's canonical-only rule rejected it with -10868, so voice chat never
started recording (issue #75 trace: 20 attempts, all failing there).
A real AUHAL converts any linear PCM; element 1 now accepts native-endian
float32 or 8/16/32-bit integers in either layout, which PulseAudio records
and RenderBus copies. Playback (element 0) keeps the canonical rule.

The input check gains a Vivox-style run: interleaved stereo 44.1 kHz with
the device set on element 1.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:13:16 +02:00
Kalah 20a8ea3370 Merge pull request #78 from lucannez64/fix/close-client-cooldown-boot
close-league-client-in-game: don't block closes right after boot
2026-10-18 23:20:24 +02:00
lucannez64andClaude Opus 5.5 4ae311b14e close-league-client-in-game: don't block closes right after boot
last_close started at 0.0 and the cooldown compares it with
time.monotonic(), which counts from boot. For the first 30 s of uptime
every close was refused as "in cooldown". That made the tests flaky on
freshly booted CI runners (seen on PR #76). Use None for "never closed".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 23:16:18 +02:00
lucannez64andClaude Opus 5.5 52b0fa905d riot-audio-input-check: detect a synchronous access callback by thread
The handler read a flag the caller wrote without synchronization, and
inferred "called inside the request" from whether the call had returned,
which misfires when the handler runs on another thread first. Compare the
handler's thread with the caller's instead and keep the shared results
atomic.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 23:08:48 +02:00
lucannez64andClaude Opus 5.5 5c8226f3e2 Pass microphone input through CoreAudio and AVFoundation
Voice chat (Vivox) saw no capture device and Chromium was told mic
access was denied. Fixes for issue #75:

- AVCaptureDevice: audio is Authorized when CoreAudio has a default
  input device; requestAccess answers asynchronously. Video stays Denied.
- PulseAudio input device reports 2 channels on input scope, 0 on output
  (was copied from the output device).
- PulseAudio input stream: real sample/host timestamps, one device
  buffer per IOProc call, holes as silence, IOProc errors no longer cork
  the stream, record buffer attrs sized to the device buffer.
- AUHAL: two elements per scope like macOS, non-blocking
  AudioUnitRender on bus 1 with planar support, device records in the
  bus 1 format, input-only units route CurrentDevice/BufferFrameSize to
  the input device, input start errors handled.
- New offline check tools/riot-audio-input-check.cpp.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 22:55:11 +02:00
Kalah a594fda49a Merge pull request #73 from PolarSeeker77/fix/x11-transparent-windows
X11: give transparent windows an alpha visual, float translucent splash windows
2026-10-18 20:57:01 +02:00
Kalah a8f17f7bea Merge branch 'main' into fix/x11-transparent-windows 2026-10-18 20:56:29 +02:00
Kalah ecc5b812bb Merge pull request #72 from 3AvisD/fix/close-league-client-in-game
fix(launcher): close the League client UI while a match runs
2026-10-18 20:56:18 +02:00
Kalah 70841d6080 Merge pull request #71 from 3AvisD/fix/mesa-shader-cache
fix(launcher): keep Mesa's shader cache on the host
2026-10-18 20:56:15 +02:00
lucannez64andClaude Opus 5.5 957b960985 close-league-client-in-game: start the idle clock only after a client was seen
A long patch or login can keep the League client closed for more than ten
minutes after launch; the helper then left before the first match.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 20:48:43 +02:00
3AvisD efc92dfb04 fix(launcher): keep Mesa's shader cache on the host
Mesa derives its shader disk cache from $HOME. Inside the guest that is
/Users/<user>, which does not exist on the host filesystem, so Mesa could not
create the cache and disabled it, once per process:

    Failed to create /Users/<user> for shader cache (Permission denied)---disabling

One launcher log contained 212 of those lines, and no shader compiled by one
process was reused by another process or by the next start: the client and the
game recompiled every shader on every launch, spending CPU at startup for no
gain.

Mesa is host code loaded into the guest and reads MESA_SHADER_CACHE_DIR verbatim,
so point it at a host directory; Mesa creates mesa_shader_cache/ (client and game
shaders) and radv_builtin_shaders/ below it. A non-empty value from the caller is
preserved, and a directory that cannot be created leaves the previous behaviour
instead of ending the launch.

Observed on a Radeon RX 550 with radv: no shader-cache failure after the change,
and 434 files / 5.6 MB written during one client start, still growing while the
client ran. The cache is reused from the second start on, which lowers the
client's CPU use while it starts; the startup-time gain itself has not been
measured separately.
2026-10-18 12:18:33 -06:00
3AvisD bc8fa71a7f fix(launcher): close the League client UI while a match runs
The client does not come back properly after a match when its own "Close client
during game" option is enabled. The UI (LeagueClientUx and its helpers) is a
Chromium/CEF instance and, under Darling, the pre-match instance keeps running:
the client the backend starts when the match ends is a second CEF instance on the
same --user-data-dir, and its window never paints. Its DOM and audio work and the
window stays black; closing the client by hand during a match leaves the same
state for the same reason.

RCLOL_CLOSE_CLIENT_IN_GAME=1 opts in to closing that UI from the host, and only
while a match runs, so the client that appears afterwards is the only instance.
The UI also competes with the game for CPU: on a four-core host with a Radeon
RX 550 a practice match reported roughly 120 FPS with the UI running and roughly
180 FPS with it closed. This is not the helper-killing memory optimization the
RAM section warns against, and the Riot client, the League backend and the game
are never touched.

The helper fails closed. It attributes the game and the client to the launcher's
prefix through the loader's __mldr_sockpath, since guest processes do not carry
DPREFIX (checked on a live session). It never closes a client younger than 60
seconds (the one the backend starts after a match), preserves a process of
another installation or owner, acts only when the environment and the stat fields
can be read, gives up after three closes in one match, and leaves after ten
minutes without a client or a match. It is off by default.

Tests use fake /proc entries and mock every signal.
2026-10-18 12:18:33 -06:00
Polar 57c65b8225 X11: alpha visual for transparent windows, float translucent splashes
Riot's splash screens draw on a black rectangle: LeagueClient's is a
borderless NSWindow with setOpaque:NO and a pattern-image background, the
Riot Client's an Electron BrowserWindow with transparent: true. X11Window
created every window with a 24-bit visual and -setOpaque: only stored the
flag, so there was no alpha channel.

A non-opaque window whose background can show through (alpha below 1, or a
pattern image) now gets the 32-bit ARGB visual. League's game window is
non-opaque on an opaque background and stays on the opaque visual, which
X11IsLeagueGameWindow also enforces. The X window exists before apps set
opacity and background, so the choice is checked again when the first
subwindow is created (layer subwindows inherit the visual) and before the
first map, and the window recreated while unmapped if it changed. Its
background is transparent instead of None, so no black frame shows before
the first draw. Its surface comes from an alpha EGL config for that visual
(CGLGetWindowWithAlpha) and its compositing context from the surface's
config (CGLCreateContextForWindow): NVIDIA refuses the default config on a
32-bit window, and no driver makes a context from it current on the alpha
surface. Without an alpha config the window falls back to the opaque
visual.

A translucent window above the normal level (Electron's alwaysOnTop
splash) is typed _NET_WM_WINDOW_TYPE_SPLASH with _NET_WM_STATE_ABOVE before
it is mapped: window managers float it and draw no frame around it.
Electron's level never arrived, though: CGWindowLevelForKey returned the
normal level for every key, and the SDK turns NSFloatingWindowLevel into a
call to it. It now returns the levels macOS does; Cocotron only stores
levels, so nothing else changes.
2026-10-18 17:49:10 +00:00
Kalah d24f26ee63 Merge pull request #70 from DavidutzDev/feat/prefix-location
Add darling-lol --set-prefix to keep the prefix on another drive
2026-10-18 19:14:32 +02:00
lucannez64andClaude Sonnet 5.5 2be6d0d6bd Make --set-prefix safe against data loss
Stage a cross-filesystem copy in a private directory instead of deleting a
pre-existing PATH.partial, reject destinations inside the overlay work
directory, save the new path before deleting the old prefix, and verify that
the target keeps user.* xattrs before and after copying. Add tests.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-18 19:04:30 +02:00
lucannez64 2d33de4162 Merge remote-tracking branch 'origin/main' into pr70 2026-10-18 19:03:04 +02:00
Kalah 0184089710 Merge pull request #63 from PolarSeeker77/fix/x11-drag-and-drop
Drag and drop on X11: run drags in-process so CEF/Electron pages don't freeze
2026-10-18 19:00:20 +02:00
lucannez64andClaude Sonnet 5.5 8cad24c706 Add standalone X11 drag-and-drop check for PR #63
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-18 18:59:43 +02:00
David GhegheaandClaude Opus 5.5 48ae75855f Add darling-lol --set-prefix to keep the prefix on another drive
The prefix holds the installed clients and game (about 40 GB). The Nix
launcher always exported DPREFIX=${DPREFIX:-~/.darling}, so the prefix saved
in build/config.json was never used and the only way to move it was an
environment variable in every launch context.

- The launcher uses DPREFIX if set, then the saved prefix, then ~/.darling.
- darling-lol --set-prefix PATH runs scripts/nix-prefix.py in the namespace,
  whose root owns the prefix files, so cp -a keeps their owners and xattrs.
  It renames the prefix when possible; across filesystems it copies to
  PATH.partial and removes the old prefix and its overlay work directory
  only after the copy completes. A PATH that already holds a Darling prefix
  is used as it is. It refuses non-empty directories that are not prefixes,
  nested paths and paths with commas or colons (overlayfs separators), then
  saves the path with configure.py --prefix.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 18:32:14 +02:00
Kalah 9abbb917f0 Merge branch 'main' into fix/x11-drag-and-drop 2026-10-18 18:21:33 +02:00
Kalah 78a47d633f Merge pull request #64 from DavidutzDev/feat/stop-and-signal-cleanup
Stop Darling on Ctrl+C, terminal hangup and darling-lol --stop
2026-10-18 18:15:32 +02:00
Kalah 888a4bbb8f Merge pull request #62 from DavidutzDev/fix/nixos-nvidia-egl-paths
fix(nix): let EGL find NixOS GPU drivers in the FHS environment
2026-10-18 18:15:29 +02:00
Kalah 46bd7ca472 Merge branch 'main' into feat/stop-and-signal-cleanup 2026-10-18 18:15:02 +02:00
Kalah 0a92d75ce1 Merge branch 'main' into fix/nixos-nvidia-egl-paths 2026-10-18 18:15:00 +02:00
Polar 7eabb937ec AppKit: retain the drag destination and its window during a local drag
The drag loop runs run loop sources and main queue blocks between moves,
and Chromium can tear down a web view or close a window there. Hold both
until the drag ends, after -draggedImage:endedAt:operation:.
2026-10-18 16:08:26 +00:00
Kalah 49888217e6 Merge pull request #68 from lucannez64/pr61/system-profiler-overview
system_profiler: hardware and software overviews from IOKit and sysctl
2026-10-18 17:33:03 +02:00
lucannez64 fca543a62d Merge remote-tracking branch 'origin/main' into pr61/system-profiler-overview
# Conflicts:
#	.github/workflows/source-check.yml
2026-10-18 17:32:11 +02:00
Kalah ba640e68b7 Merge pull request #67 from lucannez64/pr61/metal-device-fixes
Metal: device edge-case fixes and a MacBookPro16,1 GPU name for Riot
2026-10-18 17:32:05 +02:00
lucannez64 7d74ed611b Merge remote-tracking branch 'origin/main' into pr61/metal-device-fixes
# Conflicts:
#	.github/workflows/source-check.yml
2026-10-18 17:31:14 +02:00
Kalah 6866c209de Merge pull request #66 from lucannez64/pr61/host-env-filter
Add an opt-in filter for host desktop-session variables
2026-10-18 17:31:06 +02:00
Kalah 33716840ca Merge branch 'main' into pr61/host-env-filter 2026-10-18 17:30:23 +02:00
Kalah b540a1021f Merge pull request #65 from lucannez64/pr61/close-inherited-fds
Close inherited host file descriptors before starting the guest
2026-10-18 17:30:12 +02:00
lucannez64andClaude Opus 5.5 59327fa9f0 Report the MacBookPro16,1 GPU name for Riot on AMD and Intel hosts
With DARLING_METAL_MAC_GPU_NAME=1, MTLDevice.name is the GPU the
MacBookPro16,1 that IOKit reports shipped with, from the host's vendor:
"AMD Radeon Pro 5500M" (vendor 0x1002) or "Intel UHD Graphics 630"
(0x8086). NVIDIA keeps its own name so the game never takes another
vendor's driver paths. recommendedMaxWorkingSetSize and every other value
stay the host's, which was the risky part of #61's identity.

The Riot launcher turns it on by default (0 or empty turns it off); other
Darling apps keep the host name. DARLING_METAL_GPU_NAME still wins.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:24:49 +02:00
34c3e4ae9f Report hardware and software overviews from IOKit and sysctl in system_profiler
system_profiler now answers SPHardwareDataType and SPSoftwareDataType (and
lists them in -listDataTypes). Model, serial number, platform UUID and
provisioning UDID come from IOKit's IOPlatformExpertDevice via ioreg; CPU,
cache and memory from sysctl; the OS version from sw_vers and uname. A
field the guest does not provide is left out.

#61 instead read a separate darling-smbios.conf written by a new
generator (gen-darling-smbios.py), with hardcoded fallbacks (an Intel Core
i9, macOS 14.7, SIP enabled). iokitd reads darling-platform.plist, so
system_profiler and IOKit could report different serials and models on the
same prefix, and the generator overwrote identities imported with
configure-darling-platform.py. Reading the guest's own APIs keeps a single
source of truth: configure-darling-platform.py remains the only way to set
or provision an identity, and it is still never run by install or launch.

tests/test_system_profiler.py runs the script under sh with stub guest
commands and runs in CI.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:17:05 +02:00
3752d9e812 Fix Metal device edge cases; keep reporting the host GPU
From #61, without the default "AMD Radeon Pro 5500M" / 4 GB identity: the
host GPU's name and Vulkan working set stay the default for every app, and
the existing DARLING_METAL_GPU_NAME and DARLING_METAL_VRAM_MB overrides
remain the opt-in. Reporting 4 GB on a 2 GB card invites allocation
failures, and under-reports larger cards.

Kept from #61:
- registryID returns MTLDeviceInfo::kDefaultRegistryID instead of 0; a
  real Mac never reports 0 and apps key devices by it.
- Vertex buffer layout and attribute arrays release the old item after
  retiring it; the retire step read the item after the release could free it.
- newDepthStencilState, newSamplerState and the device name return nil (or
  the fallback name) when Indium throws, instead of unwinding through
  Objective-C.
- MTLDepthStencilGetIndium is declared only with DARLING_METAL_ENABLED.
- The replaceRegion trace probes at most `width` bytes, which stays inside
  the first row for every pixel format.

metal.patch is regenerated in its existing file order, so the diff is
these changes only. tests/test_metal_device_info.py compiles the host
check against MTLDeviceInfo.h as shipped in the patch and runs in CI.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:14:47 +02:00
David GhegheaandClaude Opus 5.5 0a9ec5f67e Stop Darling on Ctrl+C, terminal hangup and darling-lol --stop
After the clients quit, the session kept Darling running: Riot and League
crash handlers never exit under Darling, and the idle check counted them as
clients. Ctrl+C or closing the terminal killed bubblewrap, whose
--die-with-parent then killed nix-lifecycle.py before it could shut Darling
down, which left a live server marker behind.

- nix-idle.py ignores crash handlers when deciding whether a client still
  uses the prefix.
- The launcher starts bubblewrap with INT, QUIT, HUP and TERM ignored, and
  env restores them inside. The supervisor turns them into a stop request.
- nix-lifecycle.py polls for a signal or stop request and then shuts Darling
  down without waiting for clients. It stops retrying a failed shutdown once
  the server is gone, and waits for or kills its own command afterwards.
- darling-lol --stop makes the stop request and waits for the session. If
  the session does not exit within 30 seconds, or no session holds the lock,
  it kills the prefix's darlingserver and launchd like darling shutdown,
  after checking that the marker PID is this user's darlingserver for this
  prefix.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:14:26 +02:00
03fdd25bc0 Add an opt-in filter for host desktop-session variables
RCLOL_FILTER_HOST_ENV=1 makes exec-guest.py drop host session metadata
(WAYLAND_DISPLAY, XDG_SESSION_*, XDG_CURRENT_DESKTOP, GNOME/KDE/GDM,
systemd, SSH agent, terminal, toolkit, Flatpak/Snap/AppImage, exported
shell functions) and set SHELL to the guest's /bin/zsh. It is off by
default; RCLOL_KEEP_HOST_ENV lists names to keep anyway.

Unlike the denylist in #61, the filter runs after the launcher sets its
GPU tuning, keeps everything Darling and the host graphics and audio
libraries read (DISPLAY, XAUTHORITY, XDG_RUNTIME_DIR and the XDG base
directories, D-Bus, PulseAudio/PipeWire/ALSA, DRI_PRIME, MESA_*, __GL_*,
__NV_*, VK_*, LD_PRELOAD for gamemoderun, LD_LIBRARY_PATH), and lives in
one place instead of three.

tests/test_exec_guest.py runs in CI; the launcher check also verifies
that MESA_NO_ERROR=1 and __GL_THREADED_OPTIMIZATIONS=0 reach the guest
with the filter on.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:13:24 +02:00
6b753e87c5 Close inherited host file descriptors before starting the guest
A terminal, IDE or service manager can leave descriptors open in the
launcher, and the guest inherited all of them. tools/exec-guest.py closes
every descriptor above stderr and then execs the guest command.

A shell loop over /proc/self/fd cannot do this portably: dash only parses
single-digit descriptors in redirections, so "exec 10>&-" runs a command
named 10 and ends the launcher on Debian and Ubuntu.

The launcher offline check now leaks descriptors 3, 4, 12 and 200 into the
launcher and asserts the guest sees only 0, 1 and 2. It runs in CI.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:11:36 +02:00
Polar 15c7d79e16 AppKit: run drags in-process when the backend has no drag manager
The X11 backend has no NSDraggingManager, so -[NSWindow dragImage:...]
returned at once without calling -draggedImage:endedAt:operation:.
Chromium waits for that callback before the page takes mouse input again,
so any HTML5 drag in a CEF/Electron window (the League client's emote
wheel) left the page ignoring the mouse.

NSWindow now runs the drag itself between the app's own windows, with the
drag image under the pointer, and always ends it with the callback.
X11Pasteboard sends the optional -pasteboardChangedOwner: only to owners
that implement it (Chromium's drag source doesn't; the second drag
crashed). NSView's default -prepareForDragOperation: returns YES, as
AppKit does for destinations that don't implement it.
2026-10-18 14:54:46 +00:00
David GhegheaandClaude Opus 5.5 fe90039a63 fix(nix): let EGL find NixOS GPU drivers in the FHS environment
NixOS keeps the GPU driver's EGL vendor files and external-platform files
under /run/opengl-driver, which glvnd and NVIDIA's driver inside the FHS
environment do not search. glvnd then only knows Mesa, and NVIDIA cannot open
X11 displays because its X11 support is the egl-x11 external platform. The
client fell back to Mesa's software rasterizer: garbled text in the client and
no way to present the game's NVIDIA Vulkan frames.

When /run/opengl-driver provides them, prepend those directories to
__EGL_VENDOR_LIBRARY_DIRS and __EGL_EXTERNAL_PLATFORM_CONFIG_DIRS, keeping the
FHS paths and any caller-provided value after them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 15:47:45 +02:00
Kalah 603b5a168e Merge pull request #58 from DavidutzDev/fix/chromium-temp-dir
fix(launcher): give Chromium a usable temp directory ("Not Found" client page)
2026-10-18 15:19:45 +02:00
lucannez64 57511fd5e7 Merge remote-tracking branch 'origin/main' into fix/pr58-docs 2026-10-18 15:19:05 +02:00
Kalah 455ab66161 Merge pull request #57 from DavidutzDev/fix/nvidia-580-threaded-egl
fix(nvidia): keep threaded optimizations off for driver 580 (Pascal black screen)
2026-10-18 15:18:21 +02:00
lucannez64 c29f2fc81d docs(launcher): scope Chromium temp failures and use standalone checks 2026-10-18 15:17:46 +02:00