Changelog
Every public Polaris release, newest first, with what changed in each.
Older historical tags remain in the repository for continuity, but the current public product line
starts at v1.0.0.
Unreleased
Section titled “Unreleased”v1.4.12 - 2026-09-22
Section titled “v1.4.12 - 2026-09-22”- A host in Steam Game Mode streams the Game Mode screen. A Steam Deck, or any host running a gamescope Steam session, has one screen and one Steam while Game Mode is up, and both belong to the session, so until now a client could only reach such a host from Desktop Mode. Every stream from a host in Game Mode now shows that screen, whatever stream mode is configured: the configured mode is held while the session lasts and comes back in Desktop Mode. Video comes from the PipeWire node gamescope exports, attached directly with the gamescope ScreenCast portal as the fallback, keyboard and mouse go in through the session’s libei socket, and a controller arrives as a virtual pad that Game Mode’s Steam picks up like one that was plugged in. Proven on a Steam Deck OLED on SteamOS 3.8.16. See Handhelds and Game Mode.
- A Steam title launched from a client on a Game Mode host opens in Game Mode. The launch is handed to the Steam that is running the session. A host configured for Private Stream no longer tells the client that desktop Steam is active, which made the client offer to close it first, and nothing closes that Steam: not the shutdown a Private Stream asks for, not the
steam -shutdowncleanup every Steam title carries when its stream ends, and not a shutdown kept over from Desktop Mode. Ending the session on purpose (End Session on the client, Close App or Disconnect in the console) asks only the title the stream opened to close. A title that was already open on the device is joined without a second launch, which Steam would answer with “Game already running” drawn over the game, and it is left open when the session ends. A client that drops, a paused session that times out, or a Polaris that restarts closes nothing. A Steam title set to launch through Big Picture is launched once, directly, since Game Mode is Big Picture already. - A stream that starts on a Game Mode screen that is standing still gets its first frame. gamescope sends a frame only when the window in front draws, and it remembers the last one it sent across viewers, so the client showed black until someone pressed a key. Polaris now asks that window to draw once.
- A launch that fails after it was admitted in Game Mode closes the title it opened. When capture or the handoff to the client failed, the rollback stopped the session without calling that an end, and ending on purpose is the one thing that closes a title in Game Mode, so the title stayed open with no stream attached.
- A stream that paused before the host went into Game Mode says why it cannot resume. In Game Mode every launch streams the Game Mode screen, so a paused Private Stream no longer matched and the resume got a bare 409. It is refused with
game_mode_started_since_pauseand the fix: end the session and start the game again, which streams the Game Mode screen. - Touch lands where it is aimed in Game Mode on a Steam Deck. gamescope gives a touchscreen it cannot tie to a screen, which is every virtual one, the orientation of the screen it is showing, and a Deck’s panel is mounted right side up, so each tap from a client was turned 270 degrees and landed somewhere else on the screen. Polaris now works the turn out the way gamescope does, from whether the screen is external,
--force-orientation, the panel’s orientation and its shape, and turns each touch back before sending it. Touch is also placed against the Game Mode screen when gamescope fits that screen into a larger frame with a bar down each side. - The Desktop tile opens on a Game Mode host right after Polaris restarts. A client’s first look at a host after a restart can be its settings and its game list, and both still named the configured Private Stream, which a Game Mode host cannot run, so Nova planned another mode and refused the Game Mode mirror the host answered with. Those answers name the mirror now, as the profile a launch asks for already did.
- Nova’s Desktop tile opens Desktop. The library left out the entry named Desktop and showed the Low Res Desktop sample in its place, whose prep command sets an X11 output named HDMI-1 with xrandr and fails on nearly every host, so every desktop stream started with a failed command. The library now lists Desktop, leaves out the sample while it is unchanged and a Desktop entry exists, global prep commands or not, and new installs no longer get it. An apps.json already on a host is not changed, and a Low Res Desktop someone edited stays in the library.
- The SteamOS install starts Polaris at boot. It runs
sudo -H polaris --setup-host --enable-headless-boot, where it used to leave boot start as a second step, so a Steam Deck keeps Polaris running between Desktop Mode and Game Mode from the first install. The Update Center’s SteamOS command keeps boot start as the host has it, so an update never turns it back on after--disable-headless-boot. - A host that may not announce itself on the network says so. SteamOS ships avahi with publishing turned off, and Polaris logged
avahi::entry_group_new() failed: Not permittedat every start; it now says clients will not find the host on their own and names the addresses to add it by. The SteamOS guide says how. - Conditions a host is in on purpose are no longer logged as errors: a Polaris binary set up without KMS capture, a host with no desktop Wayland session, as in Steam Game Mode or at boot, and a GPU without an AV1 encoder, whose refusals FFmpeg reports as errors during the encoder check. A host set to KMS capture whose binary lost the permission to an update still gets the error and the command that fixes it, and a host that never asked for KMS no longer gets a “Silent failure” for it.
- A VA-API host’s H.264 encoder is read right. The encoder check decomposed every unit of its test frame, and a VA-API encoder at constant bitrate pads frames with filler data FFmpeg cannot decompose, so one unreadable unit failed the whole frame: the SPS went unread, the check reported that the encoder writes no VUI, and each H.264 stream then tried to rewrite an SPS it could not read. Polaris now decomposes only the parameter sets and slice headers it needs, for H.264 and HEVC alike, and a frame with no active SPS returns nothing instead of crashing the reader.
sudo -H polaris --setup-hostrefreshes the Bazzite KMS runtime copy when it has fallen behind the package. The Bazzite guide made/usr/local/bin/polaris-kmsduring every install until 1.4.5, and no package update touches a file under/usr/local, so those hosts kept running the build they first installed:rpm -q polarisreported the new version while the console reported the old one, and a copy older than 1.4.8 could not say why. Setup now compares the copy with the packaged binary, replaces it and restores its DRM/KMS capability when they differ, and says to restart the service. Only that one path is ever replaced, and only by the packaged binary.- The Update Center says when the host process is older than the console it serves. Every build serves the web files the package installed, so after an update the console is new even when the process behind it is not. A host older than 1.4.3 reports no installed package version and one older than 1.4.8 no running binary, so until now such a host only ever read “Update available” for a package that was already installed. It now reads “Console is newer than the host”, with the restart and the
--setup-hostrefresh to try, and it needs no release check to say so. - The gaming runtime for NVIDIA graphics borrows this PC’s own driver files instead of carrying a copy of one driver version. A driver update no longer strands a Space, and no longer needs a new runtime image, a new Polaris release and a move of every Space. Polaris checks each file first: owned by root, where the driver package puts it, and built for the architecture it claims, then passes it to the Space read only and never changes it. A Space made on an older runtime keeps working and can move to the borrowing one from its card.
- Host Setup gains an NVIDIA driver files check while an NVIDIA driver is loaded. It names this distribution’s own 32 bit driver package when that half is missing, which is the case that otherwise shows up as a 32 bit game rendering nothing under Proton.
- A Space can run Heroic Games Launcher or Lutris, beside Steam. Heroic reads the games installed through its Epic, GOG and Amazon backends, Lutris reads its own database, and both show in the client’s library with the launcher’s own tile first, so a title starts from Nova like a Steam one and runs on Proton or Wine inside the Space. A controller reaches those titles. Heroic’s own menus do not see a controller yet in a Space; use touch or the mouse there.
- A Space is made by naming its launcher. The Spaces page lists every launcher this PC can make a Space for, says before creating the first Space of a launcher that its runtime will be downloaded, a few gigabytes, and follows the job as it runs. A Space copies the runtime of a live Space of its launcher, so only the first one downloads anything. The page no longer promises a Steam sign-in: a Heroic or Lutris Space keeps a sign-in of its own.
- Typed text reaches a Space. A Moonlight client sends a key with a high byte set, and the Space input read all sixteen bits and dropped every key it did not know, so only a few bare keys such as Escape ever arrived.
- A title started from a launcher in a Space shows on the stream. The launcher’s environment named gamescope’s own Wayland socket, a title that finds one takes it, and with no Steam to say which window is the game gamescope ranked it below the launcher, so a Heroic title ran at full speed behind Heroic’s library.
- A launcher window fills the stream in a Space. Lutris opened at 800x600 in the middle of the stream with black bars at both sides, although the Space starts gamescope with
--force-windows-fullscreen: the pinned gamescope sizes a window that names its own size to that size in both places the flag should reach. The runtime carries the upstream fix for both. - A Space is offered the newer build of its runtime. A move was offered only when a Space’s image was built for another NVIDIA driver or a runtime that borrows this PC’s driver became available, so a fixed runtime could never reach a Space that already borrowed the driver.
/api/multiseat/profilesgains the reasonruntime_updated, on any graphics. - A Space on an older build of a runtime that borrows this PC’s NVIDIA driver starts. Whether a Space borrows the driver was asked of the catalog alone, so once the catalog named a newer build, a Space still on the older one got no driver files, its worker stopped with
libcuda.so.1 did not arrive, and the client heard only that the Space’s runtime did not start. - A Space stream no longer sends a keyframe every half second. The Space encoder ran a fixed 60 frame keyframe interval, which at 120 fps is a bitrate spike and a quality pulse twice a second on an 8 Mbps stream. It now sends a keyframe when the client asks for one, as the host encoder does.
- When the Spaces controller stops admitting launches for a pass, the log says why: the reconcile line carries
backend_observation_errorwith the inventory’s own reason, such as a timed out listing. A worker rejected because its container does not match its launch now names the part that differs. - A Heroic Space starts with Heroic’s update check off, so the image’s pinned Heroic no longer opens a dialog over the whole stream telling the player to update through a package manager a Space does not have, and the Heroic and Lutris runtimes carry
xz, without which no Windows game could be set up. A GTK launcher draws its icons inside a Space: Lutris aborted before its first window because GTK’s image loader asks for a sandbox a Space refuses. - A Space library names a cover only where one can exist, the launcher’s own poster and a title the artwork providers can look up, so a client stops asking for artwork that was never there, and the launcher tile keeps its poster while the library itself cannot be read.
- Mouse and keyboard reach a game under
gamescope_stream. That mode had gamepads only: the one compositor-local input route is for labwc, so mouse and keyboard fell through to host uinput, which a headless Gamescope has no seat to read. Polaris now speaks to Gamescope’s own emulated-input server over libei, the road XWayland’s XTEST support already takes, and Unicode text goes the same way. The route is built whenlibei-1.0is present, every official package now carries it, and when the socket cannot be reached input falls back to host uinput exactly as before. - Under Gamescope, touch and pen from the client are no longer forwarded to the host desktop.
- The pointer is visible in a
gamescope_streamstream. Gamescope keeps its cursor out of the PipeWire capture unless asked, on the grounds that a consumer would draw its own, and Moonlight and Nova draw none.POLARIS_GAMESCOPE_COMPOSITE_CURSOR=0turns it off again for a client that does. - Polaris on a
gamescope_streamhost no longer exits when it restarts its own gamescope (#744). Such a host runs Polaris withDISPLAYpointing at the Xwayland of the idle gamescope, which Polaris stops and starts again for an HDR session, for a nested session and to recover the idle compositor. The system tray held an X connection to that server, and when the server went away Xlib ended the process from inside the tray’s event loop, with no log line and no cleanup, which looked from a client like the session dying during launch. The tray now stays off a display Polaris restarts and the log says why; a desktop’s own display keeps its tray. - A packaged gamescope session wrapper runs (#745). Polaris ran the
polaris-gamescope-sessioninside its own package before any on PATH, so a packager’s wrapper, the one that exports which gamescope the session should use, never ran: on NixOS the nested session took the distro’s gamescope, without the HDR capture patches, or failed to start at all under the security wrapper PATH offered.POLARIS_GAMESCOPE_SESSIONnow names the launcher to run and wins when it is an absolute path to an executable file, the Nix module sets it to its own wrapper, and a stale copy on PATH is still named as before. Reported with a full diagnosis by kubicgruenfeld. - A host that streams through Gamescope’s portal capture can offer HDR. The encoder check at startup runs against a placeholder image that can only be 8 bit on that path, so its 10 bit attempt failed before the encoder was asked, Polaris advertised SDR only, and clients refused to start an HDR stream. That verdict is now treated as unknown there, only where the 8 bit check passed, and the live stream still fails loudly if the capture cannot carry 10 bits.
- A client profile’s HDR setting has three states in the console: Auto, On and Off. It was a checkbox, so a profile that followed the client showed as unticked, and saving the form turned Auto into a forced Off that the console could not undo. A client asking for HDR against a profile forced off got SDR where it expected PQ, which looks heavily oversaturated.
- A device can watch a stream whatever resolution it would ask for. A watcher is handed the owner’s stream as it is and a request for any other mode is refused with 412, but the mode was only said inside that refusal’s sentence. serverinfo now says what there is to watch, the stream’s size, rate, depth and codec and whose it is, and whether a game left open has anybody attached, and the 412 carries the same fields, so a client asks right the first time.
- A watcher’s request is no longer rewritten by the display mode saved for its device. A saved mode replaced the mode in every request, a watch request included, so a handheld with 1920x1080x120 saved asked to watch a 60 fps stream, asking for exactly the stream’s mode, was rewritten to 120 and refused by the watch check.
- Device Access on the Spaces page is one table. A row is a device, a column is a place it may play, Desktop and then each Space, and the last column is its Default Space. It replaces a Device Access list on every Space’s card, a Desktop Access list and a Default Space list, which took four sections to say what one device could reach. A device with one place to play is told that place, where it used to get a dropdown with one option, and Save shows only beside a choice that has not been saved. On a narrow window the same rows show as one card per device.
- The table changes every device at once. An Every device row has All and None for each column, each a single change, where letting thirteen devices into a Space was thirteen saves and every save restarts Spaces. None asks first, because the devices’ Default Space there goes with them.
POST /api/multiseat/access/alltakes a Space ordesktopandallowed, and the host picks the devices, so an out of date page cannot add one that was just unpaired. - Give Desktop Access with a Space, a switch above the table. While it is on, a device you let into a Space can open Desktop too. It is off until you turn it on, since Desktop is your whole account, and it leaves devices you have already set up as they are.
- A Space’s card is shorter. It sums up who can open it, “Retroid Pocket 6, Pixel 10 Pro and 10 more”, where it spelled out every name, and names its launcher.
- A device that was unpaired leaves the Spaces lists the next time a device’s access is changed on the Spaces page, which is also when a device that was paired again needs its access back. Unpairing never told Spaces, so the id stayed in every Space’s device list, in Desktop Access and as a Default Space for good; one test host still named a Default device that had been unpaired weeks earlier. Nothing is forgotten on a run that could not read its paired devices, where the list is short for another reason.
- The list a paired device gets of its own Spaces says which launcher each one opens, as an optional
launcherword such assteam, so a client can tell Spaces named after people apart. Nova shows it under each name in Change Space. - Leaving a Space from the client is no longer logged as
Worker media failed: the worker transport ended. Polaris let go of the worker’s connection before it marked the stream as ending, so the same clean exit was written down as an ended stream or as an error depending on timing, and with Steam Big Picture it was usually the error. - Quitting a game from inside it, in a Space, ends the stream as an ending. The launcher’s helper returned success, but the worker counted every helper that stopped as a failure, so it reported
worker runtime launcher-process-tree exited unexpectedly, left with status 1 and dropped its connection, which Polaris could only log asWorker media failed: the worker transport ended. The worker now reads how the launcher ended, tells Polaris the stream is over with theend_of_streammessage the protocol always had, and leaves with status 0. A launcher that fails, and any other helper that stops, is still a failure. What the player sees does not change: the stream ends and Nova returns to the library. This is in the worker image, so it arrives with the next published runtime. - A Space’s worker no longer reports
runtime session bus exited unexpectedly (exit status 0)and a failed stop after a clean disconnect (#734). The worker stops each helper by signalling its process group, so the helper’s child could exit a moment before the helper heard its own stop. This is in the worker image, so it arrives with the next published runtime. - Changing a device’s access to a Space answers “Space access saved”. It answered “Default Space saved”, and when the change failed the Spaces page said the Default Space was not saved.
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.11 - 2026-09-19
Section titled “v1.4.11 - 2026-09-19”Host Virtual Display on KDE Plasma gets the game, the controller and the touch it was missing, Spaces keep working across an NVIDIA driver update and a reboot, Mirror Desktop streams again when the capture setting does not fit the desktop, and couch co-op gets clearer. Nova 1.4.11 comes out alongside it. Existing configurations and paired devices remain valid.
- Host Virtual Display on KDE Plasma 6 uses KWin’s own screen by default, even with EVDI loaded. The automatic order tried EVDI first, and an EVDI screen on Plasma is a monitor like any other: it kept whatever layout KWin had stored for it (a 1.35 scale on the test host) and was not primary, so a game opened fullscreen on the primary monitor while the stream showed an empty desktop. The KWin screen is placed at scale 1, ranked after your monitors and gets the game, as tested live with Hades. The automatic order is now the KWin screen on Plasma, then EVDI, then Hyprland, then kscreen-doctor, a Plasma host that gets the KWin screen no longer has the EVDI module loaded for it, and a Backend set to
evdistill uses EVDI. - Host Virtual Display on KDE Plasma gives the game the focus on the stream screen. KWin moved the window there but kept the focus at the desk, so the game ignored the controller and taps until someone clicked it on the host.
- Touch and pen from the client land on the KWin stream screen. KWin spread them over every monitor, so a tap landed wherever that point fell on the whole desk. Polaris ties them to the stream screen while it exists and unties them when it goes, undoes a tie to its own screen that a crash left behind, and keeps a tie you made yourself in System Settings.
- Your monitors stay where they are when Host Virtual Display starts on Plasma. KWin applied a layout it had stored for “these monitors plus a Polaris screen”, which on the test host moved a monitor 1024 pixels to the right for the whole stream. Polaris now puts every monitor back where it was in the same step that places the stream screen.
- The Doctor names three Host Virtual Display problems on Plasma: another backend used in place of the KWin screen, with the reason; a stream screen at a scale other than 100%; and touch or pen that could not be tied to the stream screen, with KWin’s answer. Troubleshooting lists every host finding now, not just the first, and a finding that needs nothing done reads as a note. The Virtual Display panel says why a KWin screen could not be used.
- Spaces work with NVIDIA driver 615.71.09. The NVIDIA runtime bakes in the NVIDIA userspace for one driver version, and 1.4.10 shipped only the 610.57.04 image, so a host that updated its driver was told to download a runtime that did not exist for it. A 615.71.09 runtime is now published, signed and admitted next to the 610.57.04 one, and Host Setup picks the one that matches the driver loaded on your PC.
- A Space made before an NVIDIA driver update can move to the runtime for the new driver and keep its Steam sign-in and installed games. A Space keeps the runtime it was made with, and that runtime carries the NVIDIA userspace for one driver, so after the host updated its driver the Space started with a mismatched userspace and failed without saying why, and the only way back was a new Space with an empty Steam home. Polaris now refuses that launch before anything starts, with
space_runtime_driver_mismatchand a fix Nova shows, and the Space’s card on the Spaces page says which driver it was made for and which one the PC runs. Move To The Runtime For Driver downloads the runtime for the loaded driver when it is missing, then points the Space at it and changes nothing else: its home, name, network, devices and Default Space stay, and the home is not prepared again. A move is refused while a Space stream or another change to Spaces is running, and when the new runtime needs a different kind of home, and a move that stops partway leaves the Space as it was./api/multiseat/profilesgainsruntime_driver,host_driver,runtime_mismatchandruntime_moveper Space, withruntime_move_availableandruntime_move_job; the move isPOST /api/multiseat/profiles/runtime. - Spaces survive a reboot that renumbers the graphics devices. Guided setup saved the card’s
/dev/dri/cardNandrenderDNpaths, and the kernel does not keep those numbers from one boot to the next: an EVDI display or another GPU that starts first takes them, so after an ordinary reboot Spaces stayed off with a log line about the separate input owner that had nothing to do with it. Polaris now finds the card by the PCI address setup saved with it and uses the card and render nodes that address has on this boot, in memory only, so the saved configuration is left as setup wrote it. Only nodes the kernel lists under that exact device are used, the container still gets real/dev/drinames, and the NVIDIA device nodes are checked as before and never rewritten. When the card is gone, its driver has not loaded yet, or its nodes no longer match setup, Spaces stay off and the log says which, and turning onmultiseat_moonlight_inputalongside Spaces gets a line of its own. - A desktop stream uses the capture backend Polaris found. With Mirror Desktop and
capture = wlron KDE or GNOME, which have no wlroots capture protocols, the capture-source check substituted another backend and Polaris said it was using it, but every stream still asked for wlr by name, found nothing and ended a moment after it started, and Nova showed “Error code: -1”. A stream now asks for what the check can serve: a private labwc session always asks for wlr, a substitution makes it ask for auto so it lands on the substitute, and a session that owns an exact output or runs in Gamescope keeps the configured backend. - Changing the host default stream mode from Nova rechecks capture. The change was saved and applied live, but capture stayed checked for the old mode until a restart, so Private Stream asked a Mirror Desktop list for wlr and found nothing. The change is now logged, capture is checked again when no stream is running, and a launch checks again whenever the configuration changed since the last check. The chosen encoder is kept, so the client that made the change is not offered H.264 alone until the next launch.
- A launch whose capture cannot start is refused with
capture_backend_unavailableand a message naming the capture method and the mode, instead of starting and dropping the connection a moment later.kms_capture_needs_capabilityandno_capture_backendkeep precedence where they apply. polaris --helpexplains--setup-host, each of its options, and points atpolaris --setup-host --help.- A device that only watches a stream no longer adds a controller to the host. Every session created controller 0 when it started, a watcher’s included, so a couch co-op game counted a second player that nobody held.
- The Steam Controller (2026) gets an emulated DualSense when the client says that is what it has, as Moonlight’s development builds do. The DualSense carries the controller’s gyro and its touchpads, which an Xbox pad dropped, and the two touchpads land on the left and right halves of the DualSense touchpad so a game sees both. A pad created before the app launched keeps what the client declared, so the split works there too.
- Troubleshooting’s controller test names every player on the host and the pad each one emulates.
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.10 - 2026-09-18
Section titled “v1.4.10 - 2026-09-18”Spaces open up, a paired client can put the host to sleep, and Host Virtual Display on KDE Plasma gets a screen of its own from KWin. This is the first release whose compiled runtime catalog admits published Steam runtimes, so a Space can be created on a released build. Completion estimates, Find Cover, ROM folder emulators and support bundles got attention too. Nova 1.4.10 comes out alongside it, and Sleep Host needs both. Existing configurations and paired devices remain valid.
- A Space can be created on a released Polaris. The runtime catalog compiled into this build admits the two Steam runtimes published to
ghcr.io/papi-ux/polaris-worker-steamby digest: one for NVIDIA hosts on driver 610.57.04 and a default one for AMD and Intel. Host Setup downloads the one this host needs without registry credentials, and first Space setup completes. The NVIDIA runtime was exercised end to end on an NVIDIA host, from the same published bytes to a played Steam game and a clean teardown; the default runtime has not run on AMD or Intel hardware yet. The runtime packages move to the 2026-09-18 snapshot, which carries the libinput and PipeWire fixes. A host on 1.4.9 keeps its empty catalog, so creating a Space needs this update. - Support bundles, pre-filled GitHub issues, copied support text and the evidence sent to an AI explanation no longer carry network addresses. Credentials were already redacted by name, but an address has no name in front of it, so a line such as a client’s session start went out with its address in full. Each address now becomes a label that keeps what kind it was, such as
lan,cgnat(the range Tailscale uses on IPv4),tailscale,link-localorpublic, and stays the same throughout one export, so a bundle can still show a client moving from the LAN to a tailnet without saying which address it had. Loopback, multicast and example addresses stay readable. The support bundle version is now 5. - Host Virtual Display on KDE Plasma 6 gets a screen of its own from KWin instead of borrowing one of your monitors. KWin creates the screen for each stream at the client’s resolution, Polaris places it beside your monitors and asks for the client’s refresh rate with kscreen-doctor (120 and 144 Hz work when KWin accepts the mode), and the screen goes away with the stream, or with Polaris if it stops. The screen is ranked after all of yours and never made primary, so Plasma leaves every desktop, its icons and its panel on the monitor they were on; a small KWin script loaded for the stream moves windows that open during it, the game included, onto the stream screen, and leaves the desktop’s own prompts, such as polkit’s, where you are. No EVDI, dummy plug or VNC server is involved. KWin virtual screens carry no HDR; an HDR request streams SDR and the Doctor says why. The new
linux_virtual_display_backendsetting (Backend, on the Virtual Display panel) picks EVDI, KWin, Hyprland or kscreen-doctor instead of the automatic order, applies without a restart, and a chosen backend that cannot run refuses the launch with its reason. KWin never offers a screen to a Polaris that holds the capability--enable-kmsgrants, so with Backend set to KWin and capture left onautoorportal, Polaris drops it at start./api/vdisplay/statusgainsbackend_preference, and/api/vdisplay/backendslists the KWin backend. (#727) - When Polaris drops the capabilities its binary carries, for a portal capture path or a host set to KWin screens, it now does so right after reading its configuration, before it starts any thread, and refuses to make the process dumpable while another thread exists. The drop used to run after logging had started a thread, and
capset()changes only the calling thread, so that thread keptcap_sys_admininside a process other programs of the same user could attach to. - A private headless stream no longer rebuilds its whole capture and encode pipeline about once a second while the screen is still, as it did while Steam Big Picture loaded at the start of a session. The stream turns cursor painting on at its first frame, and the ext-image-copy capture reused the session it already had, which cannot change that setting, then waited on it for a frame an idle screen never sends. The session is now created again with the cursor setting the stream asked for, and a new session sends its first frame at once. Every path that used to rebuild without a word now logs why.
- The Doctor says how the client reached the host and how its display mode was chosen, and keeps both after the stream ends, since a support bundle is usually exported after disconnecting. Session Snapshot gains Network path (
lan,cgnatfor the range Tailscale uses on IPv4,tailscale,link-local,publicorloopback, never the address), which on a tailnet says to runtailscale pingon the client to see whether Tailscale is relaying the stream, and Display mode. When a device’s Display Mode Override replaced the mode the client asked for, which is why such a client cannot choose 1080p, the Doctor checklist shows a Display mode warning that says where to clear it. Both reach the Doctor evidence and the pre-filled GitHub issue. A host that could not raise its capture and encode thread priority reports that as a host configuration warning with the limits that applied, instead of only in one log line at the first stream./api/stats/streamgainsclient_network_pathanddisplay_mode_decision(requested,applied,pinned_by_host). - A paired client can put the host to sleep. Turn on Allow Clients To Sleep This Host in Settings and a paired client that is not watch only can suspend the machine with
POST /polaris/v1/host/sleep; Polaris refuses while a stream is still running.GET /polaris/v1/host/power, and the same block on the capabilities response, say whether this host can sleep, whether the setting is on, whether the calling client may ask, and why not when the answer is no, so a client can offer the control only where it will work. A host whose polkit wants interactive authentication for suspend, which is what usually breakssystemctl suspendwhen Polaris runs it, is named aspolkit_deniedwith the rule to allow instead of failing quietly. - Host sleep reports whether the host actually slept. logind can accept a suspend and still fail it, for example when a task blocked in a FUSE mount will not freeze, so Polaris watches for thirty seconds after the request and serves
last_sleep_outcome(none,pending,suspendedorfailed),last_sleep_reason,last_sleep_messageandlast_sleep_aton the host power block. Nova 1.4.10 uses it to stop saying the host went to sleep when it stayed awake. - The configuration docs gain Before you turn it on, four checks for host sleep that were all found on one working desktop: the firmware wake setting and the cold power-down it needs, why
Wake-on: gproves nothing, USB devices that wake the host again within seconds, and a task stuck in a network or FUSE mount that aborts the suspend. - Settings, General says under Allow Clients To Sleep This Host whether this host can sleep, before any client asks. When it cannot, it says why: polkit wants a password a remote request cannot give, with a link to the rule that allows it, the host reports that it cannot suspend, or logind did not answer. It also says when the last sleep request was accepted and the host never went down. New console route:
GET /api/host/power. - Find Cover in the app editor works again. It looked covers up from the browser, which the console’s content security policy blocks, so the panel stayed empty. It now runs Nova’s SteamGridDB search on the host: you can change the name it searches for, up to five matching games that have a poster show with their titles and years, read from all ten SteamGridDB returns so “Heroic” finds Heroic Games Launcher, picking a game shows up to five of its posters as Nova’s Artwork Studio does, the previews come from the host, and a missing key, a SteamGridDB failure or a search with no match each say so instead of showing nothing. A missing key links to the field in Settings. The saved cover is the full image, not the preview. The console routes are
GET /api/covers/search?name=&uuid=,POST /api/covers/choiceswith{uuid, provider_game_id, title, steam_appid},GET /api/covers/preview/<token>?uuid=andPOST /api/covers/selectwith{uuid, token}. - A cover saved in the console shows on the Apps and Dashboard pages at once. The cover route told the browser to keep an image for a day under a URL that names the entry rather than the image; it now revalidates each cover against its file.
- A launcher, an emulator or a desktop entry no longer shows a completion time. The estimate is looked up by title, and a launcher’s title is an ordinary word, so the Heroic entry was given the hours of a game called Heroic Dungeon. Only an entry that names one game is looked up: by Steam app id, by ROM file, or by the id a Heroic or Lutris import carries for its game. A manual entry is taken at its word, and an estimate already saved for a launcher is no longer shown.
- Completion estimates resolve again. How Long To Beat renamed its search routes in September 2026 and retired the old ones, so every lookup failed without a word and the dataset stopped growing. Polaris uses the new routes, and a lookup outage now logs one warning until the next success instead of nothing. A short title no longer takes a longer one’s estimate: the match allowance scales with the title’s length, so “Eden” no longer matches “BioEden”.
- The Heroic launcher entry has its own poster,
heroic.png, drawn like the Steam and Lutris ones around Heroic’s icon. New imports publish the entry with it, and an existing launcher entry without an image gets it once when Polaris starts. - Nova shows a launcher’s bundled poster (
lutris.png,heroic.png). The name was read against the working directory, so only the utility entries resolved theirs. - Changing an entry’s image reaches Nova. Polaris kept the poster it copied the first time, so a second cover pick or another file left Nova on the old one; a cleared image now also stops showing the copy.
- A cover picked with Find Cover after artwork was picked for the entry in Nova now shows in Nova. The Nova pick outranked the entry’s image, so the console showed the new cover while Nova kept the old poster. Saving the entry now drops the picked poster and keeps the picked background, logo and icon. Any other image keeps the pick, whether you typed the path yourself or a library rescan refreshed an imported cover.
- Find Cover asks for a name when the entry has none instead of opening an empty panel, and a failure the host gave no reason for says so in words rather than as an HTTP status code. When the console sign-in has expired, it says to sign in again.
- An emulator install from Flathub that finishes while you are on another console page is reported when you come back to Apps, and the folder list is scanned again, as it is when you watch the install finish.
- The right-click menu on an empty Private Stream screen can be read. Its notes were cut off at labwc’s 200 px menu width, so they looked like buttons that did nothing (#715). The notes are shorter, and Polaris writes a
themerc-overridebeside its labwc configuration that gives the menu more room; one of your own is left alone. - Session Snapshot’s Network path calls the
cgnatrange “Tailscale or another VPN” and a link-local address “A direct cable”, and the tailnet note leads with what to do when the stream stutters. - The app editor’s Needs command badge and Command: Missing summary count a detached command, so launcher entries such as Heroic and Lutris no longer look broken.
- A game imported from a ROM folder launches the emulator this host has now. An entry saved while its emulator was missing kept the bare binary name, so installing the Flatpak afterwards still started an empty session with a black screen; launch now resolves the folder’s emulator file,
PATHand the Flatpak each time, and a launch whose emulator is still missing is refused withemulator_not_installed, naming the emulator, the game and the fix. A command you edited after import runs as you wrote it. - A missing preset emulator can be installed from the ROM folders panel with Install From Flathub. The host runs Flatpak for its own account without a shell, adds the Flathub remote for that account only when it is missing, shows the install on the folder card while it runs, and points that emulator’s imported games at the Flatpak when it finishes. A failure shows Flatpak’s own reason (DuckStation is no longer on Flathub). New route:
POST /api/library/emulators/install;GET /api/library/sourcesgainsinstallableandinstall_jobon presets and folders. - Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.9 - 2026-09-16
Section titled “v1.4.9 - 2026-09-16”A setup update shaped by a fresh install: quick setup covers the encoder, the launch mode and a trusted network as well as artwork and AI explanations, saved settings apply without a restart, restart from the console and the tray works again, Nova’s artwork alternatives work, a Space can be removed for good and its host setup fixed from the Spaces page, and host setup, the KMS guidance, the Spaces helper and the Spaces page say what they found. Nova 1.4.9 comes out alongside it, and Nova 1.4.8 keeps working with this host. Existing configurations and paired devices remain valid.
- A saved SteamGridDB key or AI provider setting takes effect while Polaris runs: the cover search, Nova’s artwork search and AI explanations use the new value at once. The save response carries
restart_required, and the settings page and the first-run wizard ask for a restart only when a saved change still needs one. - Host setup removes an
/etccopy of the udev rules or modules-load configuration that an older Polaris installed, recognising every version Polaris shipped, and its closing summary names a copy it keeps because that copy may hold a local edit. - Every Polaris install or update replaces the binary without the KMS capture capability. The startup log, the Doctor, a refused launch and the package notes now say to run
sudo -H polaris --setup-host --enable-kmsagain after each one. - KWin screencast permission entries are one per binary: an update no longer adds another
dev.polaris-stream.app.Polaris.kwin.*.desktopfile, and the entries Polaris wrote for binaries that no longer exist are removed. - Virtual display cards such as evdi no longer log a missing render node or the NVENC different GPU warning; real GPUs still do.
- The Linux desktop entry and its Run in Terminal action carry the Polaris icon (every package except openSUSE shipped
Icon=empty), and the tray’s playing, pausing and locked icons each carry their own badge. polaris-spaces-setupnames what it refuses: SELinux modules it does not manage with their priorities and thesemodulecommand that removes them, the Polaris processes still running, and an input rule that differs from the packaged one. An input rule identical to the packaged one is adopted instead of refused.- On a build without a published gaming runtime, the Spaces page reads as ready and waiting: the Gaming runtime check becomes a neutral waiting row left out of the count, standing in for the Spaces configuration check, Host Setup says Host ready, and nothing says host preparation comes first.
- Restart from the console and the tray works again and cooperates with systemd. The request no longer depends on a SIGINT that any shell command running at that moment could swallow, which is how a saved SteamGridDB key never reached the running host. Under
polaris.servicePolaris now exits with status 75 and the unit starts the installed binary, so a restart after an update runs the new version; other launch paths re-execute in place as before, andsystemctl stoporrestartalways gets a real exit instead of a process that outlives the stop timeout. - AI explanations in Codex subscription mode follow the Codex CLI. The model list comes from the catalog the CLI caches for the signed-in account, the CLI’s configured model is the default and replaces the hosted-API pre-fill in the settings tab, and a request Codex refuses shows Codex’s own sentence (for example that a model is not supported with a ChatGPT account) in the test result and the log instead of a bare exit code. The Claude hints move to Sonnet 5 and Opus 5.
- The first-run wizard gains two optional steps. Artwork checks a SteamGridDB key against SteamGridDB before saving it (a new
POST /api/covers/key/check, which never stores the key), and AI Explanations offers the provider choice, sign-in, model list, test and enable from the AI tab in a compact form. Both steps can be skipped, both say that the host reads the new settings after a restart, and the last step offers that restart. The SteamGridDB field in Settings says the same. - Host Virtual Display says what it will do on a KDE host without EVDI. There the kscreen-doctor fallback cannot add a display; it borrows a connector and resizes it, and the mode card now says so instead of promising an added display. The kscreen-doctor setup panel stays on the settings page after a connector is saved, lists the connectors the host found, says when a new choice still needs a restart, and warns when the connector is the primary output, is lighting the desktop, or has nothing plugged in. The settings page also re-reads the host’s display capabilities when you come back to the tab, so a restart from the tray or systemd no longer leaves the mode card and the panel showing the answer from before the restart (#633)
- Host Virtual Display can be chosen again on a KDE host that relies on the kscreen-doctor fallback while it runs another mode, such as Private Stream. Loading the configuration retired
linux_streaming_outputfor modes that own no connector, and the defaultheadless_swap_modemade that happen on every start, so the mode read as unconfigured and its card stayed greyed out asking for a connector the file already had. A mode switch from a client also erased the connector frompolaris.conf. The connector in the file now keeps Host Virtual Display available and is what the fallback borrows, while modes that own no connector still retire it for capture, and the dashboard preview no longer crops a private session to it. The same holds for a connector left from Headless Dongle: on a host without EVDI, Host Virtual Display is now offered with that dummy plug, and an app that asks for a virtual display on a host that is not streaming privately borrows it (#633) - The app editor shows Mirror the host desktop on Linux. It was already why the bundled Desktop entry streams the real desktop on a Private Stream host, but it could only be changed by editing
apps.json, and the launch modes and troubleshooting guides still said Desktop opens an empty private session. New entries now save the setting explicitly, and both guides and the app editor reference describe what Desktop actually does and how to get an empty private session instead (#715) - Docs: the README catches up with 1.4.8 (the Spaces preview and its limits, the ROM folder library, 240 FPS on created displays, refusals that say why, the capture forecast), and a Spaces or regular streaming page puts the two side by side in one table, linked from the Spaces guide.
- Docs: an uninstall page in the order that works: the Spaces policies first while the helper still exists, then the package, then what the package leaves behind (rule copies under
/etc, a/usr/share/polaristhat other files kept alive, the Spaces security record, your own additions) and~/.config/polariswith a keep-or-wipe table. Every distribution page links it. - Docs: the Spaces guide explains the security helper’s three refusals (a policy at another priority, a Polaris process still running, an input rule it did not install) and the fix for each.
- New installs start in Private Stream: the first start writes
linux_stream_mode = headless_streamwhen labwc and wlr-randr are on the PATH, and a host without them, such as SteamOS, keeps Mirror Desktop. Existing configurations keep their mode, and the bundled Low Res Desktop entry mirrors the desktop like Desktop does. - On a build without a published gaming runtime, the Spaces page says plainly that a Space cannot be created yet, points at regular streaming meanwhile, and leaves out the setup steps that cannot run.
- Removing a Space can now delete it for good. Remove Space offers two choices: archive, still the one selected, which keeps the Space’s games and saves for Restore, or remove for good, which deletes its installed games, saves and Steam sign-in once you type the Space’s name. An archived Space offers Remove for good beside Restore. The host checks the typed name itself, refuses while any Space stream runs, keeps the last Space because new Spaces are made from an existing one, and deletes through Docker only the volume and network it created for that Space, proven by their label, driver, options and mountpoint. If Docker stops partway the Space stays archived and removing it again finishes; the response names a volume or network left behind (
kept_volume,kept_network), and/api/multiseat/profilesannounces the ability asremoval_available. - Two Spaces host checks can be fixed from the Spaces page. Polaris access to Docker offers Give Polaris access to Docker, which starts Docker, sets it to start with the PC, and adds the account Polaris runs as to the docker group, and Spaces security support offers Install security support. Polaris runs the packaged
polaris-spaces-setupthrough pkexec with one fixed operation (POST /api/spaces/setup/host-action), and polkit opens the password prompt on the host’s desktop, so someone signed in at the host approves every change and a browser elsewhere can only start the request. The packages shipdev.polaris-stream.app.Polaris.policywith one action per operation, each asking for an administrator every time. Polaris refuses in words on an image based host, without the helper, pkexec or that exact policy, without an active local desktop session, or while a Space, a stream or the first Space setup is active, and Space launches and Spaces changes, Remove for good included, wait while a change runs. The helper leaves only the Polaris that asked out of its busy check, counts a running Space by its SELinux domain, and gains adocker-accessoperation; the Docker access check says when the account already joined the group and only a restart of the PC is missing. The terminal steps stay beside each button. - Nova’s artwork alternatives work.
POST /polaris/v1/games/<id>/artwork/choices/<kind>lists up to five SteamGridDB images of one kind for a chosen match, each as an expiring selection token whose preview the candidate route serves, and the match route applies picked tokens given asselections. A pick replaces only the kinds it names, keeps the other custom images, and commits every pick or none. An expired or foreign token gets a 409 withartwork_choice_expiredorartwork_choice_mismatch, and capabilities announceartwork_choices_v1when a SteamGridDB key is set. Earlier hosts had no such route, so Nova said the alternatives could not be loaded. - Quick setup has eight steps: Credentials, GPU and Encoder, Launch Mode on Linux, Network, Artwork, AI Explanations, Pair Client, and First App last because it leaves the wizard. GPU and Encoder reads the new
GET /api/setup/hardware, which lists each GPU with its driver and the codecs VA-API can encode, the encoder Polaris picks and why, and advice such as the Mesa driver swap an AMD card needs on Fedora for H.264 and HEVC. Launch Mode saves the same settings the Settings page writes for a mode. Network lists the private networks on this PC’s real interfaces fromGET /api/setup/networks, so the home network can be trusted with one click, and a saved trusted network now applies to pairing at once, without a restart. - Host Setup on the Spaces page has a Gaming runtime check. It names the runtime this PC needs, the NVIDIA build for the loaded driver or the default one, says when the build includes none or the driver does not match, and offers Download, which fetches and verifies the runtime without preparing a Space. When the runtime is already on the PC, first Space setup prepares without a download and its button says Prepare.
- Spaces turned on from the Spaces page can start and change. First Space setup wrote the marker that ties the Spaces IPC directory to its controller inside that directory, where the Space workers’ startup check refused it, so no Space could start and every Spaces change failed with Space settings could not be restored until a restart. The marker now sits beside the directory, and a host set up by an earlier build repairs itself at its next start. The Spaces controller also logs why it cannot close or rebuild, where it used to fail without a word.
- Developers: a lab build can compile another Spaces runtime catalog and pull runtimes from another registry with the CMake cache options
POLARIS_SPACES_RUNTIME_CATALOG_FILEandPOLARIS_SPACES_RUNTIME_REPOSITORY, to test Spaces end to end without publishing a runtime. Release workflows never set them, and a unit test fails if one does.containers/multiseat/RUNTIME-DISTRIBUTION.mdhas the steps. - The game library marks Steam Big Picture on the desktop with
steam_big_picture, by the rule Polaris already uses for its Big Picture launch and cleanup handling: the bundled name, or a command that opens Big Picture on an entry that is not a Steam game. Nova’s Play Setup can then pair it with a Space’s Big Picture in either direction, where it used to grey out the other side because Big Picture has no Steam app id to match. A client that does not read the key sees no change. - Automatic artwork only takes a match that is the entry. A Steam title finds its SteamGridDB game by app id, and any other entry takes a SteamGridDB search result only when its title is the entry’s name, ignoring case, punctuation and trademark signs, instead of the first result, which gave Low Res Desktop the artwork of Low Magic Age. Entries that stream the desktop never look artwork up, and artwork an earlier build downloaded for them is removed and never offered again. The app editor gains Remove artwork, which deletes every picture downloaded or picked in Nova for an entry and stops automatic lookup for it (
POST /api/apps/artwork/remove, a marker beside the entry’s cached artwork thatGET /api/appslists asartwork_lookup_off), and Find artwork again (POST /api/apps/artwork/find), which turns the lookup back on. - Default Space only sets where a device opens first. Saving Desktop as a device’s Default Space used to remove the device from every Space; now its Spaces stay under Device Access, so a device can open Desktop first and still change to its Space in Nova. Default Space offers Desktop once the device has Desktop Access and a Space only once the device may open it, and the host refuses anything else with a sentence that says what to tick (
desktop_access_required,space_access_required). Unticking a Space under Device Access is how a device leaves it, its Default Space included, and a device that can no longer launch games gets Remove from Spaces. The Space catalog records a Desktop default asdesktop_default_clientsin schema 5, written only when a device has one, and Nova reads it asdefault_space_iddesktop. - When two paired devices share a name, for example Nova and Nova Debug on one handheld, the Devices page and every device list on the Spaces page add when each one paired, or a number when even that repeats.
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.8 - 2026-09-16
Section titled “v1.4.8 - 2026-09-16”A Spaces preview matched with Nova v1.4.8, with a library that fills from a folder of emulator games, higher frame rates on the displays Polaris creates, and launch refusals that say why. Spaces is for configured hosts only and has no public runtime download yet. Existing configurations and paired devices remain valid.
- A refused Space launch now says why, the way a refused host launch does: Nova shows the host’s sentence and the one change that fixes it (the Space is being played on another device, this device already has a Space running, every Space slot or the encoder is taken, no Space is assigned or selected, the assignment changed) instead of “Space Could Not Start”. Host messages about Spaces use the words the console and Nova use: Space, never profile or seat, and one sentence for “stop the Space streams first”.
- The Spaces list a device reads now says why, not just whether:
unavailable_reasonwhen the host cannot offer Spaces to it (the controller is missing, stopping or reconfiguring, or no Space is assigned to the device),switch_blocked_reasonwhen a stream must end first,default_space_id, the host’s Space budget ascapacity(concurrent_limit,concurrent_active, also on the console’s/api/multiseat/profiles), and per Spacecan_openwith ablocked_reason(in use, starting, stopping, at capacity), so a second player sees “one Space at a time” before pressing Open instead of after. The capabilities route announcesspaces_v1on any host with Spaces, whichever Space or Desktop the device has picked, and the Space session status saysstartingduring the start window. All of it is optional keys on the existing schema. - First Space setup says what blocks it. The setup snapshot carries
unavailable_reason(already_configured,runtime_not_published,journal_fault,journal_locked,closing), the job carriesblocked_by(journal_fault,runtime_withdrawn,no_eligible_gpu,closing) and, when its journal could not be secured, arecoveryrecord naming the retained image and reference, and every host check carries adoc_anchorinto the Spaces guide, so the console can link the fix instead of showing a dead button. The one thing the job cannot report is download progress, and the docs stop claiming it. - The Spaces console speaks the console’s grammar. Every string is translatable (a
spaceslocale namespace instead of English literals in eight components), Space status and host checks render as the same status badges Doctor uses, Remove, Restore and the setup restart go through the confirmation dialog with Escape, a focus trap and the change’s impact spelled out, the restart reconnects on its own through the shared host-restart helper instead of asking you to, and the buttons, inputs, checkboxes and disclosures are the shared ones. Polling pauses while the tab is hidden and backs off while the host does not answer, and a background refresh no longer disables every control for a moment every ten seconds. A running Space stream now disables the controls it blocks and says which device to stop, instead of sending the request to a refusal; a Desktop Access grant reports its real result (it always read “not confirmed” before); the page no longer shows “Create your first Space” before the first snapshot has loaded or when the load failed; a host’s refusal reason reaches the message on 400-class errors; archived Spaces are no longer offered as the base for a new one; a card’s device list and its Device Access list apply the same permission filter. Host Setup leads the page until the host can offer Spaces, checks sit two per row and link the guide section that fixes them (the host’s owndoc_anchorwhen it sends one), the Docker and security steps for your distribution are on the failing check with a Copy button (package installs are withheld on immutable hosts), the first-setup card says why the download is unavailable, what blocks the job and what was kept for recovery, and the sidebar marks Spaces as a preview and lists it on Linux hosts only. - Docs: the Spaces guide is rewritten in the order a player meets it (what a Space is and whether you need one, Docker, the host checks with one section per check, the first Space, recovering an interrupted setup, more Spaces, device access, playing, renaming and removing, sound, what to do when it fails), with the preview status, capability tables, audio protocol and catalog notes moved to
research/container-multiseat-preview-status.mdbehind one “Preview limits” link. Nova’s Spaces payloads (spaces_snapshot,space,spaces_capacity,space_library,space_library_game,space_ref,space_launch_mode,space_legacy_game) are declared indocs/nova-contract.json, built by one function each so the contract audit reads their shape from the source. - Spaces preview: an optional Spaces tab manages separate Steam sign-ins, games, and saves. Assign paired devices, allow access to additional Spaces, rename player environments, or remove and restore them while retaining their data. Ordinary streaming keeps its existing setup.
- Spaces guides Docker and security setup on the host, with persistent preparation progress and retry controls. First runtime download remains unavailable until an approved image is published; initial setup permits one active Space. See the setup guide and current acceptance results for supported paths and remaining audio limits.
- Import games can bring emulator games in from a ROM folder. Add the folder and the emulator in the import console (Eden, Dolphin, Cemu, DuckStation, PCSX2, PPSSPP, mGBA, or your own command with
{rom}in it); every file the emulator can load becomes a candidate named from its filename with the region and version tags removed, update and DLC dumps are skipped, the entry launches the emulator straight into the game with the pad the platform expects, and the emulator itself is published once next to its games. The folder is remembered, so a rescan finds games added later, and covers come from SteamGridDB when a key is set. (#699) - Docs: an emulators guide covers the whole path for emulator games, from what each emulator needs before a game boots (keys, BIOS, a Flatpak allowed to read the folder, the pad to map once) through import and covers to saves on End Session and the Nova face-button choice.
- Quitting a private-compositor session now gives the app its own Exit Timeout to leave after SIGTERM (at least two seconds, at most thirty) before SIGKILL; it was a fixed two seconds regardless of the setting, which cut an emulator’s save write short. Entries imported from a ROM folder get ten. An app that ignores SIGTERM now holds End Session for its timeout instead of two seconds.
- A ROM folder card names what its emulator still lacks before a game boots, with the fix: Eden’s
prod.keys, Cemu’skeys.txt, a BIOS image for DuckStation or PCSX2, or a Flatpak that cannot read the folder (checked against its metadata and overrides, with theflatpak overridecommand spelled out). The add-folder form shows the same for the chosen emulator, and Library health counts the folders that are ready. - A ROM folder import picks up a cover that already exists: next to the game (
<name>.png, or acovers,boxartormediafolder beside it), in ES-DE’s downloaded media for that system, or among RetroArch’s boxarts for it, native or Flatpak. The image is copied into Polaris’s covers directory and set as the entry’s artwork, so console and Nova show it without a SteamGridDB key. - The library list tells Nova what a ROM folder entry is: emulator entries carry the console as
platform(switch,psx,gbaand so on) and the emulator asruntime, withplatform_labelandruntime_labelnaming them, and the host announceslibrary_emulators_v1. A client that reads the labels shows “Nintendo Switch · Eden” on the tile; the JSON library route’ssourcefilter also accepts any source name as apps.json spells it. - A launch command that single-quotes an argument, such as a path with a space or an AppImage under a folder with a space, is now split the way a shell would before it runs. The command runner kept the quotes and split the path in two, so such an entry never launched; commands without single quotes or backslashes run exactly as before.
- The support bundle keeps two previous runs instead of one, so a freeze, a reboot and an export no longer lose the run that had been streaming, and it carries the kernel’s GPU-related lines for this boot and the previous one (NVIDIA Xid, i915 hangs, hung tasks, other stacks’ virtual display modules) when the journal is readable, saying so when it is not. A Polaris that cannot bind its RTSP port now names the process holding it, since every Sunshine-family host uses the same port, and keeps that reason in the crash record instead of “unspecified”.
- The Doctor now pairs the encoder node Polaris actually uses against the GPU the compositor renders on, whether
adapter_namewas set or Polaris chose the node itself, and knows the compositor’s GPU before any stream has started. On a hybrid laptop that names the split (iGPU desktop, NVIDIA encoder) with both ways out: keep everything on the iGPU, or keep NVENC and turn off NVIDIA runtime power management. Virtual display drivers (evdi, vkms, hermes-kms, vibeshine_drm, udl) are no longer counted as GPUs when Polaris picks an encoder node. Docs: a hybrid laptop section and the order to bisect a whole-machine freeze in. - The console’s system-stats poll no longer re-enumerates the host’s Wayland outputs every three seconds. Each enumeration was a fresh client connection to the compositor with a DMA-BUF feedback round trip and nine log lines, and on a laptop that hard-froze during a Mirror Desktop stream the freeze landed on one of those polls while KWin was reading the screen back for the stream. The display list is now cached: refreshed at most every 30 seconds while idle, once when a private-compositor stream starts or ends, never during a stream of the desktop itself, and the enumeration logs at debug so a support bundle keeps its evidence instead of two thousand copies of the monitor list.
- A refused launch now says why. Every place the host refuses a launch records a reason, and the launch and resume responses carry it as the message the client shows, with the one change that fixes it, plus stable
error_codeanderror_actionattributes for Nova. A failed encoder probe names the capture cause when there is one (no capture backend, KMS without the capability) and the NVENC driver detail when that is the reason; a private compositor that did not start, a declined screen sharing prompt, a missing labwc, a virtual display that could not be created, and the previous session still tearing down each get their own code. Moonlight shows the message; before this, all of them were “error 503”. - Says which binary is really running.
--setup-hostreports a user service pointed at a copy of the binary that no longer exists, with the two ways out, and warns when the service runs a copy outside the package that updates will not touch; the Update Center names that copy instead of asking for a restart that would change nothing; the Doctor and the support bundle carry arunning_binaryrow. The Bazzite DRM/KMS recipe creates exactly this copy. - The Doctor now says, before any stream, when capture on this host will copy frames through system memory for the configured mode, and why: a package built without CUDA on NVIDIA, an X11 session, a hidden headless compositor that could not hand over DMA-BUF at its last attempt, or the VA-API copy path that AMD and Intel take by design. Each cause names its one fix, and the GPU-native advice no longer fires on a build where it cannot work. The support bundle carries the forecast with
build_has_cuda. - The Ubuntu 24.04 package is built with CUDA from this release, like the Fedora and Arch packages, so NVIDIA hosts on Ubuntu get the GPU-native capture path instead of a copy through system memory. The Arch package now points at
nvidia-utilsas the NVIDIA runtime dependency instead of the CUDA toolkit, which is only needed to build. - The Doctor now says when KMS capture was refused because the binary lacks
CAP_SYS_ADMIN, and names the one command that grants it, instead of blaming compositor protocols and steering you off the only capture path that carries HDR. The HDR finding names the working recipe:capture = kmswith a stream mode that shows the real HDR output. - Docs: the configuration that carries true HDR on Linux today, all five gates with the journal line that names each one, in
runtime.md,configuration.mdandtroubleshooting.md; and how to point MoonDeck Buddy at Polaris’apps.jsoninmoonlight.md. - Launches where Polaris creates the display itself (Private Stream, Host Virtual Display, Desktop Takeover, Gamescope) were capped at 120 FPS by three separate literals, and
/serverinfoadvertised a different number again, so a 144 or 165 Hz client was either refused before connecting or quietly served 120. One ceiling now, 240 by default and settable withheadless_max_refresh_rate, advertised and enforced from the same value (#686) - Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.7 - 2026-09-12
Section titled “v1.4.7 - 2026-09-12”A controller and configuration update matched with Nova v1.4.7. The virtual DualSense maps the way a real one does, and the per-user configuration directory stops being created in a state Polaris then refuses to use. Existing configurations and paired devices remain valid.
- Corrects the virtual DualSense’s button and stick mapping. Polaris advertised the HID version a USB DualSense reports while creating the pad on the Bluetooth bus, and that combination matches no entry in the controller database clients read, so they fell back to a layout from before the kernel’s PlayStation driver existed: face buttons rotated, and the triggers and the right stick swapped for each other. Clients that reach the pad directly were always correct, which is why the same pad could behave in one game and not the next (#660, #634)
- Rests the virtual DualSense with its sticks centred and its triggers released. Of the report’s six axes only three were given a starting value, so a pad nobody had touched reported both sticks pushed hard left and the right trigger half pulled until the first real input arrived (#660)
- Repairs a per-user configuration directory that a privileged run left owned by root.
--setup-hostnow hands it back to the account Polaris runs as, walking it without following symbolic links, and corrects its permissions as well as its owner (#654, #637) - Stops creating that directory in a state Polaris then refuses to use. It is narrowed to the owning account when it is created rather than inheriting whatever the account’s umask allows, which on common desktop defaults left it writable by its group and made saving credentials fail from the first run (#659, #637)
- Names the directory that actually refused, and the remedy that matches the fault. The message reported the directory above the one it had inspected, so it paired one directory’s path with another’s permissions, and it only ever offered to correct ownership even when ownership was already right (#663, #637)
- Says which driver was running when the hardware encoder did not start, so a host that silently drops to software encoding names the driver version it found instead of leaving the reason in a discarded log line (#657, #650)
- Explains that unreadable saved authorization state is not fatal: the host clears it, continues with a new identity, and says that any client paired before then has to pair again (#663)
- Stops building two files without optimisation on compilers that no longer need the workaround, after measuring that the internal compiler error it existed for is gone (#656)
- Continues the experimental multiseat foundation, still default off and unreachable in production: a negotiated media contract between worker and controller, and the DRM primary node a nested gamescope seat needs in its device catalog (#648, #662)
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.6 - 2026-09-11
Section titled “v1.4.6 - 2026-09-11”A correctness update for Linux hosts that stream a private display, and for three failures that used to happen in silence. A game’s stored virtual-display preference no longer overrides a host that already provides the session’s display, a paused session no longer changes what the host recommends to other clients, and an encoder, a driver reading and a refused directory now each say what went wrong. Existing configurations and paired devices remain valid.
- Stops an app’s stored virtual-display preference, or a client that never locked its topology, from moving a private headless host onto the host virtual display. A locked client choice, the paired always-virtual default, an explicit session stream mode and desktop mirroring all still win, so the mode stays reachable by asking for it rather than by inheriting it (#649)
- Keeps a session-scoped display override out of the topology the host recommends to other clients. The override stays in force for its own session, including the whole paused-session resume window, but is no longer read back as the host’s own default, so one client’s choice can no longer become the next client’s recommendation (#649)
- Reports when a host virtual display backend replaces an explicitly configured capture backend for that session, instead of substituting it silently (#649)
- Records which input moved a session off the host’s own topology, so a silent promotion no longer reads in the log exactly like a deliberate choice (#651)
- Adds a contract over the launch topology resolver: across every registered path and every combination of the resolver’s inputs, a private host must either defer to its own default or return a topology the caller named (#651)
- Rejects nvidia-smi’s failure banner as a driver version. The banner was stored in the driver cache, which is keyed on the tool’s path and modification time rather than its content, so a single bad reading survived restarts and stopped the encoder cache from noticing a driver change; an already-poisoned cache now heals itself
- Names the directory that refused to hold private state, along with its owner, its mode, the user Polaris runs as, and the remedy. One run under sudo leaves the per-user configuration directory owned by root, after which saving credentials fails permanently, and since v1.4.5 it failed with nothing in the log at all
- Keeps libav errors at the default verbosity instead of silencing them. An encoder that cannot start because the graphics driver is older than the linked FFmpeg’s nvenc API now reports both versions, rather than falling back to software encoding without explanation
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.5 - 2026-09-10
Section titled “v1.4.5 - 2026-09-10”A Bazzite and Live Tuning update matched with Nova v1.4.5. Live Tuning is one saved host preference that every console surface and paired client reads the same way, Bazzite Desktop launches prepare capture before the stream starts, hosts running a Steam Game Mode session learn why they go offline and how headless boot keeps them reachable, and --setup-host reports it. The supported Bazzite RPM path was exercised end to end on an NVIDIA Open host with a Retroid Pocket 6. Existing configurations and paired devices remain valid.
- Reworks the supported Bazzite RPM guide around staged installation, explicit reboot, local-RPM replacement, and boot-independent service setup; moves the composefs KMS copy into an optional section and keeps Game Mode hardware limits and the withdrawn system extension explicit
- Shares one saved Live Tuning preference across Quick Controls, the Audio/Video settings page, paired session status, and session events, independent of AI provider sign-in. Clients see the requested bitrate separately from the encoder-confirmed rate, with waiting, measuring, applying, adjusting, stable, unavailable, and unknown states; turning Live Tuning off holds the last confirmed bitrate, and an explicit fixed bitrate supersedes adaptive ownership (#641)
- Prepares desktop capture before stream startup on Bazzite, normalises the resume policy, keeps native audio ownership with the session, and corrects CUDA conversion ownership and upload ordering, so a Bazzite Desktop launch or resume no longer prepares the portal too late or inherits unsuitable display semantics (#639)
- Refreshes display capabilities once the host is back after Save + Apply, so Host Virtual Display no longer stays unavailable on the settings page because of a stale capability response; late responses cannot overwrite the new snapshot and Reset Changes keeps the refreshed capabilities (#642, #633)
- Keeps DualSense reports in order: a periodic report can no longer land after newer button updates and replay stale input; the sender and reader threads are retained and joined, and descriptors close if construction fails (#643, #634)
- Preserves the configured physical identity of every virtual input device on all nine uinput creation paths and keeps descriptor ownership until destruction, so reserved-device udev rules identify them reliably (#644, #494)
- Protects unused encoder capability probes from a null-frame flush, adds actual submission/teardown regressions for the first-launch Vulkan crash, and keeps Doctor from telling a stable AMD VA-API/SHM user to switch to Auto with a promised fallback (#628)
- Repins native PipeWire session audio when the stream omits its PID by resolving its owning client, while preserving session markers, unrelated desktop audio, and the no-default-sink-claim setting (#629)
- Recognises hosts with a Steam Game Mode session (SteamOS, Bazzite deck images, CachyOS handheld edition, other gamescope-session hosts).
--setup-hostsays why Polaris goes offline when the host leaves Desktop Mode and prints the headless-boot command,/api/stats/systemreportsgame_mode_hostwith Game Mode-aware boot readiness and display-session guidance, and the console names a running Game Mode session instead of asking for a desktop restart. New handhelds guide with the Game Mode validation recipe (#626) - Adds the experimental multiseat worker foundation (default off and unwired in production), a maintained offline system-extension assembler with locked inputs, a read-only Bazzite host observer for local acceptance runs, and steadier Doctor CI fixtures (#640, #645, #646)
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.4 - 2026-09-06
Section titled “v1.4.4 - 2026-09-06”A packaging and setup update matched with Nova v1.4.4. The application menu entry starts the same Polaris service that autostart and headless boot use, and a privileged setup run no longer mistakes root’s own device access for a ready desktop account. Existing configurations and paired devices remain valid.
- Starts the packaged user service instead of a second process. A desktop launch used to make the running service instance exit, and nothing brought it back once that window was quit or the session ended, which left a host that had been streaming fine with no Polaris until the next login. The menu entry, autostart, and headless boot now all point at the one service
- Stops a privileged
--setup-hostrun from treating root’s own access to/dev/uinputand/dev/uhidas proof that the desktop account is ready, so a user still missing the input group is reported instead of passed - Adds a fail-closed Bazzite validation receipt checker that binds candidate bytes, source identity, image and driver identity, SELinux results, and physical hardware results, and runs it before release artifacts are bound
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.3 - 2026-09-05
Section titled “v1.4.3 - 2026-09-05”A diagnostics and packaging update matched with Nova v1.4.3. Doctor names the gamescope session helper Polaris will run, the console and Nova get a coded answer when an artwork search fails, and partial configuration writes merge instead of rewriting the file. The standalone system extension initially shipped with this release and was withdrawn on September 5, 2026 because it did not include the runtime dependencies required by Bazzite. Existing configurations and paired devices remain valid.
- Shows a Gamescope Session Helper card in Doctor & Support on Linux hosts configured for
gamescope_stream, naming the launcher Polaris will run, a stale copy shadowing it on PATH, and a launcher or runtime library installed from a different checkout - Falls back to the bundled
polaris-gamescope-sessionreference copy when no launcher is installed beside the binary or on PATH, so AppImage and build-tree hosts can start private sessions, and adds a shell test that exercises the gamescope stack installer - Adds
PATCH /api/config, which merges a partial write onto the existing configuration instead of rewriting the file from the request body the wayPOSTdoes, and logs how many existing keys aPOSTleft out - Names the cause when an artwork search fails: the Nova-facing candidate search and the console cover search now answer with a stable code for a missing SteamGridDB key, a rejected key, rate limiting, or an unreachable provider instead of a bare status or an empty result
- Names the field when explicit launch fields are rejected, including the value seen, so a comma-decimal
fpsor a lock flag without its prerequisite no longer reads as “must be complete and within supported bounds” - Tells the console when the installed Polaris package is newer than the running process, which is what a package upgrade without a service restart looks like
- Withdraws
Polaris-sysext-x86_64.raw; do not use cached copies. Bazzite remains supported through the Fedora 44 RPM andrpm-ostree - Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official package assets
v1.4.2 - 2026-09-04
Section titled “v1.4.2 - 2026-09-04”A stability and diagnostics update matched with Nova v1.4.2. Polaris lets a capable Nova client choose the encoder for a single game, closes a Linux Vulkan Video crash at disconnect, keeps SteamOS’s gamescope file capability from breaking private streams, and stops stale helper installs from being debugged as Polaris bugs. Existing configurations and paired devices remain valid.
- Fixes a Linux Vulkan Video crash at client disconnect by closing FFmpeg’s codec-owned picture views before releasing Polaris’s converter resources, and records bounded teardown phase markers for field verification
- Advertises the encoder backends compiled into the host and lets a capable Nova client choose one for a single game without rewriting
polaris.conf. Among per-game choices, Auto is the only fallback policy; an explicit backend is live-probed strictly, bound to the deterministic launch envelope, reported in session status, and restored to the host default at teardown. Persisted host choices retain their existing fallback behavior, except Vulkan which remains strict - Keeps harmless low-latency LAN RTT jitter from reducing the Auto Safe bitrate, and keeps a clean Auto Safe recovery informational in Doctor while confirmed media loss still warns
- Makes machine-facing decimal parsing and formatting locale-independent across
/optimize, display planning, launch profiles, compositor arguments, and telemetry, so a host running under a comma-decimal locale can launch again, and keeps GTK tray initialization from changing Polaris’s numeric semantics - Starts the private nested gamescope compositor with
no_new_privs, so thecap_sys_nicefile capability SteamOS and Arch ship on gamescope can no longer hide/procownership from the same-user checks that prove which compositor owns the stream; desktop Game Mode keeps its capability - Runtime-masks the idle compositor unit only where one exists, repairs a leaked runtime mask on the idempotent stop path, and classifies the scripts/install layout of an idle unit with the host portal as
host-portalinstead of refusing it as inconsistent, so standalone packages and manual installs no longer wedge after a failed start - Skips the private portal rebind on hosts without a private portal unit instead of polling an absent bus for eight seconds and logging a warning that read like a failure
- Resolves
polaris-gamescope-sessionbeside the Polaris binary before PATH, ships reference copies of the helper modules, and reports at launch when the launcher in use is shadowed by a stale copy or was installed from a different checkout - Captures a labwc startup client’s exit status and a bounded, redacted stderr tail when no private-session window appears, and records bounded per-session evidence for encoded frames that exceed the four-block FEC protection envelope; both stay informational in Doctor unless corroborating media-loss or pacing evidence exists
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.4.1 - 2026-09-03
Section titled “v1.4.1 - 2026-09-03”A matched performance, access, and Linux workflow update for Nova v1.4.1. Polaris adds guarded experimental Vulkan Video for supported Linux DRM/KMS paths, memory-only guest pairing, Hyprland Desktop Takeover, and more precise Doctor and capture evidence. Existing configurations remain valid, and automatic encoder selection falls back when the exact Vulkan requirements are not met.
-
Adds memory-only guest pairing for Nova QR and Manual PIN clients, with explicit access controls and automatic revocation after the device’s final stream disconnect or a Polaris restart
-
Adds an explicit Hyprland Desktop Takeover mode that creates a client-sized virtual output, moves the live workspaces onto it, blanks the original displays with DPMS, and restores the exact workspace layout before removing the virtual output on final disconnect
-
Adds an experimental Linux Vulkan Video encoder for H.264 and HEVC across DRM/KMS, wlroots, and Portal capture; Auto promotes it only on a compatible AMD private-stream route with an exact live-frame safety probe and VA-API fallback, while an explicit Vulkan choice stays strict and AV1 remains disabled until the bundled FFmpeg path passes Vulkan validation
-
Keeps Vulkan image imports and cursor overlays safe across asynchronous submissions with per-slot fences and descriptor sets, and exposes low-latency CBR tuning plus explicit KMS setup guidance in Settings
-
Pins the prepared FFmpeg bundle carrying Vulkan queued-picture teardown and missing encode-queue error fixes, preventing capability probes and short sessions from leaking image views or opening a broken encoder
-
Separates fresh-install Welcome setup from upgrade and reinstall sign-in across every supported distro guide, preserves existing host state by default, routes hosts with stored credentials away from the first-run wizard, and surfaces the real credential persistence error instead of a generic internal-server message
-
Makes
Game Controlthe default for every newly paired Nova or Moonlight-compatible client, providing the browse, launch, and input permissions needed to play without granting clipboard, file-transfer, or server-command access; renames the old non-launchingStandard Accesslabel toBrowse & Watch, while leaving every existing device’s saved permissions unchanged -
Shows the host cursor by default for new or unset configurations so Moonlight-compatible clients retain a usable pointer, including on DRM/KMS capture where the hardware cursor uses a separate plane; preserves explicit disabled settings, Nova’s per-session coordination, and the runtime toggle
-
Preserves write-only SteamGridDB, AI, and legacy API credentials when Settings or Quick Controls saves an otherwise complete redacted configuration; clearing a stored key now requires its explicit clear action
-
Keeps deterministic Doctor output as the source of truth while allowing a configured provider to explain its redacted evidence; OpenAI subscription mode now invokes the signed-in Codex CLI through a private, bounded explanation-only workspace, and provider failure remains an informational
deterministic-fallback -
Starts imported Flatpak Heroic titles through the launcher’s normal visible cold-start protocol path instead of hiding the only actionable launcher feedback; exact older commands generated by Polaris migrate in place without changing UUIDs, artwork, profiles, prep commands, or custom fields
-
Keeps transient stream startup work from becoming a frame-pacing verdict by collecting six complete video telemetry windows and requiring two consecutive warning observations; Doctor reports the incomplete window as unknown and retains its read-only pacing action
-
Grades encoder time against the active stream’s real FPS budget, keeps a measured-healthy SHM compatibility path informational instead of inventing a 60 FPS recovery, avoids recommending a GPU-native mode that already fell back, and points an AMD Private Stream explicitly pinned to VA-API toward Auto’s Vulkan live probe with VA-API fallback
-
Reports missing private-session managed-window evidence as inconclusive for fullscreen and XWayland surfaces instead of claiming that a working stream is empty or rendered on the host desktop
-
Carries Heroic’s recorded platform and Wine or Proton runtime into imported GOG and Epic titles, so a successful import launches through the runtime the player selected instead of discarding that per-game choice
-
Says when client keyboard and mouse seat isolation cannot take effect by reading back the seat marker on each virtual input device and warning when the host input backend dropped it
-
Names the exact wlroots connector selected for capture even when its human-readable description is blank, and preserves the regression where a requested
POLARIS-HEADLESS-*output must never fall back to physical monitor zero -
Updates the web build lockfile to patched
@humanfs/nodeandpostcss-selector-parserreleases, withnpm auditreporting no known vulnerabilities -
Reworks the Video/Audio settings tab into mode, quality, and display cards that show live host state, adds
GET /api/settings/metadataso the console knows each field’s source, sync state, and last writer, and tells host defaults apart from the values a paired device overrides -
Gives Doctor & Support, Devices, System & Updates, and Security the shared console grammar: read-only status tiles, one button vocabulary, an AI panel that reports its real readiness, a previous-run banner that separates a crash from a deliberate stop, Session Snapshot rows that name the capture path and the last writer, and a per-device view of the host settings a client overrides
-
Adds Sign out to the sidebar and the command palette, and a Clear history action on both Mission Control session lists backed by
POST /api/ai/history/clear, which also empties the AI optimizer’s stored session outcomes -
Moves the AI settings tab onto the same grammar with a guided provider setup and a readiness sentence, and gives the General, Input, Network, Advanced, and Files tabs localized headings with a pointer into the per-tab reference
-
Moves the console’s inline explanations into the documentation: new Play with Moonlight, Pair and manage devices, Add and edit apps, and Mission Control guides, a field reference for every settings tab in the configuration guide, and every (i) hint removed from the console in favour of one docs link per page and one-sentence inline descriptions
-
Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.4.0 - 2026-09-01
Section titled “v1.4.0 - 2026-09-01”A matched feature release for Nova v1.4.0. Doctor turns measured stream evidence into a clear explanation and, only when the evidence supports it, a reversible same-stream fix. Launch fields come from deterministic presets with field-level provenance, while history and AI remain unable to silently change a launch or inject a game-process limiter.
- Reports frame-pacing Watch evidence under the compatibility reason code
frame_pacing, without contradictory Stable state or unsupported network/bitrate blame; static and duplicate-only content is not treated as a pacing fault without source-cadence evidence - Removes history, recovery, and AI launch overlays; the legacy
apply_recovery_profile_next_launchaction is disabled, old recovery records are deprecated, non-applicable, and cancellable, and old apply/verify calls fail asunsupported_deprecated - Resolves
auto,quality,high_fps, andstabilitydeterministically and returns source, reason code, lock, and normalization provenance for every resolved launch field, including separate width, height, and FPS provenance for mixedhigh_fpsprofiles - Advertises the deterministic resolved-profile contract so Nova v1.4.0 refuses older Polaris launch policy rather than failing open to legacy history or AI settings
- Keeps topology exclusively under explicit app/client display semantics and stops synthesizing MangoHud, DXVK, or VKD3D frame limiters for game processes
- Binds optimize results to the canonical app UUID or ID and exact host-default, mirror, or private topology choice, advertises the versioned topology-assertion contract, and revalidates the complete deterministic profile before both fresh launch and resume
- Keeps Auto Fix only for same-stream bitrate changes with measured verification, conditional controller ownership, and automatic rollback that never overwrites a newer user/client bitrate; pacing uses Recheck or manual guidance
- Coordinates Doctor with Auto Safe: while the deterministic adaptive controller owns an active bitrate correction or recovery, Doctor explains the issue and offers a read-only Recheck instead of racing it with a stale second mutation
- Keeps the exact rollback target fixed until the encoder acknowledges it, then resumes the prior adaptive policy; verified actions return terminal copy instead of leaving clients to reuse an in-progress measurement message
- Ingests HUD-independent raw media counters from the authenticated active owner and exact stream generation, derives confirmed loss on the host, rejects stale coverage gaps, and enables acknowledged live bitrate reconfiguration for the Linux FFmpeg/NVENC path
- Binds live Doctor and paired bitrate/adaptive mutations to the exact app-session token and stream generation, retains idempotent terminal results for that whole generation, and restores Doctor’s temporary target before accepting a newer adaptive-policy choice
- Gives Nova and the Polaris web UI the same typed Doctor success, conflict, and rollback-unconfirmed response contract, preventing a failed safety check from being presented as a successful fix
- Serializes paused-session expiry with launch and resume admission so an accepted reconnect cancels its timer before the lifecycle gate is released, while an expired timer cannot terminate the newly resumed game or admit media after teardown
- Adds disabled-by-default Doctor v2 shadow evidence and a separate authenticated, private, one-dimension trial contract; records expire after a 24-hour lifetime, every trial is one-shot, and actions remain hidden until dedicated acceptance enables them
- Keeps Steam Input manual and read-only without changing VDF files, Steam state, live streams, or launch policy
- Launches imported Heroic GOG and Epic titles through the matching native or Flatpak install using Heroic’s current protocol, rejects browser-tampered runner/install metadata, deduplicates current and legacy command forms, and narrowly migrates Heroic entries generated by older Polaris releases
- Keeps built-in utility entries such as Virtual Display on their shipped host artwork instead of automatically matching an unrelated SteamGridDB game, and retires the stale automatic cache without removing an explicit Artwork Studio selection
- Clarifies Settings navigation, Linux launch modes, and capture paths around player impact; Headless Dongle remains a host-wide choice, planned modes stay visibly non-selectable, and backend details remain available without leading the decision
- Prevents wrapped nested Gamescope teardown from entering the affected 3.16 Vulkan destructor by keeping a session-owned primary child alive after exact-session Steam exits, then freezing and killing the exact marked private group; verifies whole-group kernel stop state first and positively drains separately grouped or leaderless private-session members while the keeper retains cleanup authority
- Refuses PipeWire DMA-BUF frames when the running package has no matching encoder importer; CUDA-disabled NVIDIA packages fall back to SHM/CPU capture before the first unusable GPU-only frame can reach the encoder
- Forwards non-cage detached Steam shutdown through Steam’s no-bootstrap remote client, preventing a vanished listener from starting a replacement client while preserving retry authority when generation cleanup is incomplete
- Restores distro-package Gamescope sessions to their empty compositor baseline without requiring Nix-only services, and retains the exact recovery claim when safe cleanup cannot be proven
- Restricts AI and Codex CLI output to typed explanatory text that cannot define settings, actions, confidence overrides, or launch policy; subscription
deterministic-fallbackremains informational and quiet - Retains the GCC 16, Ubuntu snapshot, exact release-source, sanitizer, Arch, public-hygiene, and CodeQL gates from the protected release base
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.13 - 2026-08-22
Section titled “v1.3.13 - 2026-08-22”A Linux runtime reliability and configuration patch. Polaris now stops the exact Steam app workload before asking the private Steam client to exit, keeps nested compositor teardown serialized and generation-owned, restores several capture and encoder lifecycle invariants, and lets the AI Optimizer clear a stored API key through the same strict validation contract used by the rest of Settings.
- Quiesces the exact
SteamLaunch AppId=<id>lineage, including token-stripped descendants, before requesting full private-client shutdown; requires the pinned Steam game-process stop event plus a bounded settle, and uses exact pidfdSIGKILLrather than entering Steam’s crashing destructor when proof is incomplete - Prevents the observed Depot Download HTTP teardown assertion by separating game removal, recording and AutoCloud exit work from global Steam client shutdown
- Serializes nested Gamescope stop transitions, preserves exact-generation compositor ownership, and sizes nested sessions from the final negotiated render geometry instead of imposing a standalone 4K120 fallback
- Releases only the EGL context a teardown thread actually bound, reprobes a missing deferred cage encoder before launch, and retires the initial GPU-native conversion object without racing active capture
- Detects Steam Input settings that can claim Polaris’s isolated virtual controller, keeps the finding after a stream ends, deduplicates aliased Steam profile roots, and offers one guarded Doctor action instead of mutating settings silently
- Redacts private-session paths from public logs and keeps CI native-build classification, sanitizer coverage, package construction,
npm audit --audit-level=high, and snapshot dependency handling fail-closed - Accepts canonical boolean spellings without changing unrelated configuration parsing and explicitly allows a typed
clear_ai_api_keyoperation while unsupported keys remain rejected - Carries forward v1.3.12’s reviewed Boost 1.92.0-1 Arch package contract, exact versioned Boost SONAME dependencies, package ELF/dependency verification, and current rolling Arch installation gate
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.12 - 2026-08-22
Section titled “v1.3.12 - 2026-08-22”An Arch packaging compatibility hotfix. Polaris runtime and protocol behavior remain the v1.3.11 line; this release repairs the published package contract that allowed a Boost 1.91-linked binary to install on a rolling system that already provided Boost 1.92.
- Rebuilds the official Arch package against reviewed Boost 1.92.0-1 inputs while keeping the immutable package snapshot and the current rolling Arch observation as separate gates
- Declares the five linked Boost providers as exact versioned SONAME dependencies, including
libboost_locale.so=1.92.0-64, so a future incompatible Boost transition fails during package resolution instead of at process launch - Inspects the finished package’s ELF
NEEDEDentries and requires every Boost SONAME to have a matching package dependency - Installs the exact finished package against current rolling Arch, requires
lddto report zero unresolved libraries, and launchespolaris --versionbefore release publication can proceed - Contains no Polaris runtime-code, protocol, configuration, or Nova client change; existing v1.3.11 configuration and Nova v1.3.7 pairing remain compatible
- Keeps exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.11 - 2026-08-19
Section titled “v1.3.11 - 2026-08-19”A support, private-runtime recovery, display-truth, and reproducibility patch. Polaris can now preserve the evidence around crashes and silent failures, accept a bounded report from an authenticated paired client, recover private Steam and owned Gamescope reconnects, find Flatpak Heroic and Lutris libraries, keep PipeWire VAAPI capture on the safe SHM path by default, and stop describing requested display state as applied until the compositor reports it back.
- Reports the effective Private Stream path instead of only the configured choice, so a fallback or pending relaunch is visible in status and support evidence
- Finds Heroic and Lutris libraries in both native and Flatpak homes, emits the matching launch command, deduplicates the two sources, and validates launcher-controlled identifiers before placing them in a command
- Lets
linux_stream_mode = headless_dongleauto-detect and configure its display topology even when display auto-management was initially disabled; this path was validated on a real 4K dummy-plug host with panel blanking and teardown restoration - Publishes
session_overridablein the mode catalog, keeping topology-swapping modes valid as host defaults while telling clients they cannot select them for one session - Verifies Hyprland mode changes from compositor read-back, tries the Hyprland 0.56-compatible fallback when the first command reports success without applying, and reports requested versus actual geometry if neither form lands
- Records abnormal termination and actions that reported success without taking effect, then carries them into the redacted support bundle and pre-filled issue handoff
- Accepts a size- and rate-bounded client report only from its authenticated paired-client certificate and stores it beside host evidence for the next bundle
- Redacts credential names across separated, camel-case, run-together, quoted, structured, numeric, and Web UI
session_idforms while keeping ordinary labels and numeric diagnostics readable; shared references andMap,Set,Date, andErrorcontents are preserved without weakening cycle handling - Normalizes one quoting layer around trusted-subnet CIDRs, rejects an empty pairing identifier before session creation, and logs the stored identifier rather than the moved-from request value without claiming the separate VoidLink stall fixed
- Marks only compositor-private Steam with
POLARIS_PRIVATE_SESSION=1, so that exact workload cannot be mistaken for desktop Steam and block a reconnect while missing or unreadable provenance remains fail-closed - Ships
polaris-gamescope-sessionand its shared runtime library in all four Linux package families with Bash dependencies and executable package receipts - Finalizes the immutable runtime chosen by each launch generation, drains only Gamescope authority owned by Polaris, and reclaims only the proven-owned
gamescope-0/gamescope-0-eisocket pair while ambiguous cleanup remains retryable and fail-closed - Warns when a client HDR request reaches a final live SDR stream, outside encoder probes and after final colorspace selection, naming the black-video/working-audio symptom and immediate SDR recovery without changing protocol behavior
- Keeps PipeWire VAAPI capture on SHM by default for local Gamescope/KWin graphs and portal-remoted streams. CUDA DMA-BUF is unchanged; exact
POLARIS_PORTAL_DMABUF=1is an operator opt-in for a host that has already proved that route, while unset, malformed, and exact0values remain on SHM - Adds the public papi-ux Matrix Space to the README and System > Resources so community chat is available beside the existing docs, source, releases, and Discussions links
- Runs every sanitizer suite the repository defines, including the five audio, input, network, pairing, and video suites that had still been omitted after the first CI expansion
- Pins the Arch build container and package repositories to the immutable
2026/08/17archive snapshot, removing live mirror database/package-pool skew from release builds - Pins sanitizer and Ubuntu APT resolution plus the DEB smoke to snapshot
20260818T000000Z, isolated from runner sources and stale indexes, with partial updates and exceeded deadlines failing closed - Keeps
npm audit --audit-level=highmandatory - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets - Keeps the evidence limits explicit: the maintainer host is KWin rather than Hyprland, native/Flatpak discovery is contract-tested without a live Flatpak launcher install, Nova’s user-facing report action opens Android’s share sheet and does not yet automatically post to the paired-host endpoint, the known 4K dummy-plug SHM capture ceiling remains performance follow-up, and the affected RX 7800 XT has not physically tested this exact safe-default candidate. This release contains the stall by defaulting VAAPI to SHM; it does not claim the underlying DMA-BUF stall is fixed
v1.3.10 - 2026-08-16
Section titled “v1.3.10 - 2026-08-16”An install, launch, and crash-containment patch: SteamOS 3.8 becomes installable, nested Steam sessions start again after a v1.3.9 regression, VAAPI private-headless capture returns to the stable SHM path after a v1.3.9 crash report, private high-refresh capture holds its output rate, HDR advertisement returns on capable Mesa hosts, and Doctor stops reporting values the encoder never applied.
- Removes the
labwcdependency from the SteamOS 3.8 package. Polaris links nothing from labwc, but declaring it pulled in wlroots0.19, which pinslibdisplay-info.so.2and forced a downgrade of thelibdisplay-info0.3.0 that SteamOS runs KWin, Mesa, and Vulkan on, so no SteamOS install could complete. labwc is now an optional dependency and the Private Stream paths report it as missing rather than taking the desktop down - Documents the pacman keyring bootstrap that SteamOS installs require. SteamOS ships without an initialized keyring, so the first transaction that downloads a dependency failed before installing anything; the SteamOS guide now runs
pacman-key --initandpacman-key --populatewhile the root is writable, and explains which stream paths work on a Steam Deck - Starts nested Steam sessions again. v1.3.9 bounded preparation commands by the app’s exit-timeout, which defaults to five seconds, while the nested Gamescope helper needs up to about forty seconds to bring up a compositor, so every launch through that path was terminated mid-startup and returned a 503, on the HDR path as well as the SDR one. Nested startup now has its own 120-second budget and nested teardown its own 30-second budget, both reporting helper diagnostics to the Polaris service journal instead of failing silently. Steam games and Steam Big Picture now take the nested session for SDR clients as well as HDR, keeping the streamed picture and controller focus under one compositor, and the unused Nix
injectAppsoption is removed rather than advertising a no-op - Contains the VAAPI private-headless DMA-BUF regression reported after upgrading to v1.3.9 by restoring the conservative system-memory route for every VAAPI capture path, including buffers exported with
DRM_FORMAT_MOD_LINEAR; affected hosts reportvaapi_headless_dmabuf_disabled_for_stabilitywithcapture_transport=shmandframe_residency=cpu, while CUDA/NVENC GPU-native capture is unchanged - Probes VAAPI HEVC Main10 with a real 10-bit P010 input surface instead of pairing the Main10 profile with an 8-bit surface, so capable Mesa hosts stop failing the capability probe and suppressing HDR advertisement; profile selection now follows the actual input format across Main, Main10, and RExt, and live-session fallback stays separate from capability detection
- Paces private-compositor screencopy capture from the compositor’s own frame callbacks instead of placing a second fixed timer in front of it, so a private high-refresh output no longer settles at a capture source below its own refresh. Direct desktop capture stays fixed-interval to preserve client-rate limiting, and output refresh, capture-source FPS, encoded FPS, and capture pacing are now reported as separate values
- Reports only adaptive bitrate targets the encoder actually applied. A rejected runtime update no longer walks an internal VAAPI target down to the 2000 kbps floor while encoding at the session bitrate, live adaptive control is enabled only for encoders that support runtime updates, and Doctor evidence tracks the bitrate in real use
- Separates Doctor’s backend detection from configuration readiness, states that Private Stream does not require the Virtual Display path, gives backend-specific configuration guidance, filters expected errors only inside the explicitly safe encoder-probe window, and reports target interval error and target FPS gap separately from network jitter
- Keeps
npm audit --audit-level=highmandatory - Builds the Nix
polaris-streampackage in CI for the first time. The job had never passed on any release: its checkout did not request git submodules, sothird-party/arrived empty and the build died during configure - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets - Records the field gates this release does not close: the SteamOS install fix is reasoned from the released artifact and Valve’s package repositories rather than run on a Steam Deck, SteamOS Game Mode remains uncertified, and the VAAPI containment still needs the affected #367 host to confirm the SHM markers and absence of a new coredump; GPU-native VAAPI performance remains follow-up work in #409; and the private high-refresh pacing fix was measured on a host that does not reproduce #434, where it raised encoded cadence from roughly 116 to 120 FPS against a 120 Hz output, so the reporting host has still not confirmed it
v1.3.9 - 2026-08-15
Section titled “v1.3.9 - 2026-08-15”A Linux reliability and security patch for private-stream capture, compositor ownership, high-refresh cadence, and hostile-input boundaries.
- Enables VAAPI GPU-native capture only for the private headless ext-image-copy route when the captured DMA-BUF is explicitly
DRM_FORMAT_MOD_LINEAR; tiled, invalid, missing, windowed-private, and direct-monitor modifiers remain on the SHM fallback, and Doctor preserves the exact fallback reason - Makes capability-enabled Polaris work with
xdg-desktop-portalby dropping capabilities before worker threads start and restoring ordinary same-user/procaccess; explicit DRM/KMS capture retains its required capability on a separate process start - Accepts capability-enabled owned Gamescope generations, warns when unsupported nested Gamescope WSI can hide a blocking dialog, and prevents owned Gamescope/Xwayland descendants from retaining Polaris listener sockets after host exit
- Creates and owns only an exact process-scoped Hyprland virtual output, verifies it before use, and fails closed instead of silently capturing a physical display
- Preserves high-refresh private-stream cadence, exposes launches that never attach, sees override-redirect windows during attach, and bounds preparation commands without releasing lifecycle ownership early
- Reapplies an explicit same-mode session choice when deterministic runtime, capture, or display companion state has drifted, while retaining the normalized no-op and teardown restoration paths
- Hardens Wayland frame ownership, VAAPI DRM PRIME descriptors, KMS render descriptors, portal/capture shutdown, session environment snapshots, and exact-generation cleanup boundaries
- Validates every client launch key, peer-declared control length, Steam app id, artwork URL/redirect hop, pairing PIN claim, and Doctor mutation boundary before use
- Keeps secondary-client telemetry while preventing duplicate control-channel network-risk samples
- Keeps
npm audit --audit-level=highmandatory - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets - Records the remaining field gates without treating CI as hardware proof: linear VAAPI headless capture still needs affected AMD 4K validation, Hyprland virtual-display ownership and same-mode session normalization need affected-host confirmation, and the supported Gamescope Stream route needs an end-to-end portal retest
v1.3.8 - 2026-08-12
Section titled “v1.3.8 - 2026-08-12”A safer private-stream daily driver: true-headless GPU-native capture, session-only launch choices, exact process ownership, an evidence-gated Doctor, bounded logs, benchmark controls, and a rebuilt web console.
- Enables a true-headless Vulkan/ext-image-copy path with a prefetched initialization frame
- Accepts a validated session-only
streamModelaunch override, re-evaluates capture sources around that session, reports display fallback explicitly, and leaves the persisted host default untouched; matching client support is versioned separately in Novav1.3.6 - Owns detached-only workloads through exact PIDFD identity before detaching, signals and reaps only the captured session generation, stops retained private compositors safely, recaptures demonstrably transient
/procraces to bounded quiescence while persistent or ambiguous attribution remains fail-closed, and hardens portal startup/cancellation and restore-token handling - Exposes evidence-gated Doctor actions to recheck, perform one guarded bitrate reduction, restore a history-safe profile gradually, verify live telemetry, and Undo through the web console; matching Nova controls are versioned and released independently
- Caps runtime diagnostics at an 8 MiB active file plus one 8 MiB backup, bounds console/file queues, preserves record-time timestamps, and exposes an authenticated binary-safe tail API with a bounded browser view and truthful truncation state
- Adds authenticated bounded benchmark-run controls and T0-T2 host-stage evidence while keeping benchmark mode explicitly gated
- Rebuilds Mission Control around one status hero, one live strip, the Doctor, a safer preview, and five Nova-aligned themes
- Hardens render-node/GPU pairing, VAAPI-safe device selection, resume refresh restoration, HDR/YUV444 capability probes, virtual-display capture routing, and launch/resume status responses
- Records the bounded Retroid Pocket 6 release smoke of the exact source commit tagged as
v1.3.8: true-headlessHEADLESS-1capture, changing frames, session-only stream mode, durable Doctor apply/verify/Undo, exact-generation teardown, and clean restoration - Keeps the remaining field-proof limits visible: the reporter’s AMD 4K60 scenario and host-virtual-display route still need current-
v1.3.8end-to-end confirmation, and SteamOS remains an experimental Desktop Mode package - Keeps
npm audit --audit-level=highmandatory - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.7 - 2026-08-07
Section titled “v1.3.7 - 2026-08-07”A use-after-free in VAAPI DMA-BUF capture that AMD hosts on DRM/KMS have been running, and CI that finally builds the nix packaging it patches.
- Fixes a use-after-free at the VAAPI DMA-BUF import boundary: the VRAM converter destroyed its imported surface before importing the replacement, while an in-flight conversion could still be using it. Reachable on DRM/KMS capture and the non-cage wlroots VRAM path, which is what AMD hosts have been running
- Fails closed on an invalid surface or texture selection rather than converting it, and closes duplicated DMA-BUF descriptors once ownership transfers
- Keeps the gamescope-polaris patch stack and the packaged compositor in step, so the
+polhdr2stamp a session negotiates against is one a build proved - Checks the vendored patch stacks on every push and builds the nix packages in CI, so a patch that cannot apply fails there rather than on a host
- Keeps
npm audit --audit-level=highmandatory - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.6 - 2026-08-07
Section titled “v1.3.6 - 2026-08-07”Client-facing fixes for Nova, host setup advice that works on ostree systems, and gamescope session and HDR capture hardening.
- Prints the input-group command that works on ostree hosts, where the group lives in
/usr/lib/groupandusermod -aG inputcannot find it; Bazzite getsujust add-user-to-input-group - Reports what the artwork resolve endpoint actually did, which Nova requires and no shipped build had ever sent, so library artwork update reported the host as unsupported
- Serves
platformandruntimeon library entries from the Lutris runner recorded at import, and only where the runner determines them - Lets a manual artwork match decide which game a completion estimate is for, without falling back to the Steam app id that made the wrong estimate confident
- Records the fields Polaris serves to Nova in
docs/nova-contract.json, derived from the source that serves them, and servesvaapi_vendorso a crash report names the driver generation - Recovers gamescope session teardown from a dead nested marker, a non-leader attach, and an incomplete attach generation that refused later launches until restart
- Negotiates PipeWire capture formats against what the stream encodes, so 10-bit PQ cannot feed an SDR encode
- Claims the stream sink as the session default while streaming, and releases that claim only from the session that took it
- Keeps
npm audit --audit-level=highmandatory - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.5 - 2026-08-06
Section titled “v1.3.5 - 2026-08-06”Package-update safety, Linux host integration owned by the package, and library playtime and completion estimates.
- Writes each mutable-distro download to the exact package filename with
wget --output-document, preventing a pre-existing file from redirecting the new payload to.1or.2while a stale unsuffixed package is installed - Makes Fedora, Arch, and Ubuntu update commands short-circuit after download, package-install,
sudo -H polaris --setup-host, or restart failures - Adds executable regression coverage for failed download, install, setup-host, and successful command paths across all three mutable package families
- Documents the v1.3.4 bootstrap caveat and provides exact-output commands for the first upgrade to v1.3.5
- Installs the udev rules and modules-load configuration as package files under
/usr/lib, so the package manager owns them and removes them on uninstall - Retires an unmodified
/etccopy from an older install that would otherwise shadow the packaged rules, and keeps an edited copy with a warning naming the file in effect - Lets
--setup-hostexit without root when the package already provides everything and the virtual input nodes are usable - Adds a
polaris-debugpackage to the Arch and SteamOS builds socoredumpctl info polarisyields a real backtrace - Closes a
systemd-inhibitprocess leaked on every session, and keeps a private session’s virtual keyboard and mouse out of the desktop session logged in at the machine - Warns at startup when seat isolation is enabled and the account Polaris runs as is not in the
inputgroup, which otherwise leaves the isolated devices unopenable by Polaris and by the streamed game - Warns when
back_button_timeoutis shorter than the 100ms Home press it emulates, since the setting is milliseconds and a value like2turns nearly every Back/Select press into Home - Reports the playtime Steam and Lutris already record on disk, and serves completion estimates from a local dataset first, with
beat_times_lookupcontrolling the How Long To Beat fallback; both are announced through/polaris/v1/capabilitiesso clients can adopt them explicitly - Adds a transactional custom artwork workflow with an authenticated resolver, bounded downloads, and atomic caching
- Surfaces per-app environment variables in the web UI
- Releases the host loopback when a session turns host audio off, instead of leaving an earlier session’s loopback loaded for the life of the process
- Applies the session’s requested resolution and refresh when preparing the streaming display
- Keeps
npm audit --audit-level=highmandatory and clears the advisories that were failing every web build - Retains exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.debas the official release assets
v1.3.4 - 2026-07-31
Section titled “v1.3.4 - 2026-07-31”Patch release adding a dedicated SteamOS 3.8 package lane and tightening Linux package, path, setup, and import safety.
- Added fail-closed packaged binary path validation with explicit source-prefix remapping and retained validation receipts
- Added secure Bazzite support for the
/hometovar/homelayout without broad canonicalization - Dispatched setup-host early and standardized public host-integration commands on
sudo -H polaris --setup-host - Made ImageMagick discovery locale-safe during Steam cover import
- Added a dedicated SteamOS 3.8 x86_64 package built against Valve’s versioned repositories, with failure-safe installation and Desktop Mode package and startup validation only
- Kept physical Steam Deck gameplay, Game Mode, OLED 90 Hz, suspend and resume, and update persistence outside the certified support claim pending hardware evidence
- Kept
npm audit --audit-level=highmandatory and the forbiddenwebtransport-go v0.10.0dependency absent - Standardized the official release on exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm,Polaris-steamos3.8-x86_64.pkg.tar.zst, andPolaris-ubuntu24.04-x86_64.deb
v1.3.3 - 2026-07-30
Section titled “v1.3.3 - 2026-07-30”Patch release focused on configuration-save hygiene, controller boundaries, Linux recovery guidance, and Nix session reliability.
- Stripped response-only runtime, stream-path, credential-presence, and virtual-display metadata before configuration saves so valid v1.3.2 settings edits no longer fail backend validation
- Kept display-planner presets idempotent across repeated selection and stale dongle-discovery responses
- Made tray URL launching locale-safe on Linux desktops
- Rebound preallocated gamepad controller feedback after device reuse so rumble and related output follow the active client
- Added default-disabled client-gamepad seat isolation with distinct virtual-controller identities and explicit Linux seat-policy limits
- Documented how Bazzite users can restore Sunshine after testing or uninstalling Polaris
- Kept Nix-composed idle/session scripts ShellCheck-clean and removed temporary authority files after failed atomic runtime publication
- Retained the exact release assets
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm, andPolaris-ubuntu24.04-x86_64.deb; Fedora 44 remains the sole Fedora package lane andnpm audit --audit-level=highremains mandatory
v1.3.2 - 2026-07-30
Section titled “v1.3.2 - 2026-07-30”Reliability patch focused on stream lifecycle, Linux private-session isolation, reconnect recovery, and truthful host diagnostics.
- Hardened RTSP follow-up control admission, live-session command ownership, session teardown, and serialized PulseAudio operations
- Prevented private-stream controller input from also navigating host Steam Big Picture while preserving normal game input
- Hardened private Steam teardown ownership and bounded interrupted process waits without broadly terminating desktop Steam
- Prevented private-session relaunch races by waiting for the prior Steam singleton to be fully released
- Preserved authenticated web sessions across host restarts and improved recovery from transient host outages
- Tolerated near-target stream FPS so healthy sessions are not mislabeled as degraded
- Exposed clearer Linux GPU probe topology diagnostics for capture-path troubleshooting
- Hardened Dashboard smoke navigation so release checks do not issue duplicate route requests
Security and release packaging
Section titled “Security and release packaging”- Updated Browser Stream to
webtransport-go v0.11.1andquic-go v0.60.0, fixing remote memory exhaustion from unknown capsule buffering (CVE-2026-57497 / GHSA-g35j-m5xg-vh3q) - Removed vulnerable, unnecessary web fixture-server dependencies and added
npm audit --audit-level=highas a permanent CI gate - Standardized the official release on exactly
Polaris-arch-x86_64.pkg.tar.zst,Polaris-fedora44-x86_64.rpm, andPolaris-ubuntu24.04-x86_64.deb; Fedora 42/43 remain historical rather than current package lanes - Added explicit Arch
vulkan-headers/vulkan-icd-loaderand Fedoravulkan-loader-develpackage requirements - Cleared GCC 15 warning-as-error blockers in Browser Stream setup, dormant preview diagnostics, and Linux display-topology helpers so exact-tag package validation builds cleanly
Linux stream modes / private runtime foundation
Section titled “Linux stream modes / private runtime foundation”- Add first-class
linux_stream_modeandlinux_private_runtimeconfig (Private Stream, Host Virtual Display, Mirror Desktop, GPU-native preference, Gamescope Stream, Headless Dongle). - Keep legacy
headless_mode/linux_use_cage_compositor/linux_prefer_gpu_native_captureas a compatibility mapping; UI and client-settings write both. - Centralize mode resolve/apply/labels in
stream_display_policy; path availability probesgamescopeon PATH (and dongle outputs at apply). - Introduce
stream_runtimeinterface with labwc and gamescope adapters so process session start does not hard-code cage forever. - Add
stream_pathregistry (runtime × capture × topology) with reserved slots for community EVDI/Family Mode paths; honestruntime_backendfor portal/host/gamescope/labwc. - Document the path plugin contract in
docs/stream-paths.md. - Enable Headless Dongle path (
headless_dongle): privacy/extended swap via kscreen-doctor (display_topology,headless_swap_mode); DRM sysfs connector discovery +/api/linux/display-outputsauto-suggest. - Enable Gamescope Stream ownership: attach idle
gamescope-0(startpolaris-gamescope-idleif needed) or spawn owned headless; wrap app launches into that runtime; never usegamescope-1for portal. - Harden portal/PipeWire capture: disconnect under loop lock; keep restore_token with invalidate+retry on SelectSources failure; wait for
AvailableCursorModes≠ 0; shared ownership so release cannot UAF negotiate/capture waiters. - Solid-base stop path: Moonlight
/cancelresponds before nested teardown; owner cancel ignores stale sessiontoken (case-insensitive UUID); Browser Stream signals shutdown, releases portal/PipeWire, then joins capture (bounded) before pidfd-killing gamescope/labwc;terminate_impland WebUI disconnect share the same prepare path. - Harden Gamescope orphan recovery and nested teardown with generation-pinned socket reclamation, shared shell/C++ ownership locking, atomic session credentials, exact private-SID/pidfd cleanup, and fail-closed portal/idle rebinding.
- Dashboard preview tries labwc, gamescope-0/1, host Wayland (grim), then spectacle — works across stream paths.
- Web UI: selectable path cards write full config (including dongle outputs and gamescope/portal capture).
- SB-5 mode-neutral Steam apps (issue #5): migration v9 + load-time normalize unwrap
polaris-gamescope-sessionhardwires tosteam-appid+ detachedrungameid; gamescope path applies attach X11 env (no host Wayland) viastream_runtime::wrap_cmd/ process. Optional Steam Big Picture may keep nested WSI shell.
v1.3.1 - 2026-07-12
Section titled “v1.3.1 - 2026-07-12”Security and pairing-state patch focused on current cryptography dependencies, durable client authorization, and clearer paired-device history.
- Updated the Browser Stream helper’s Go cryptography and supporting modules, clearing the associated Dependabot alerts
- Added localized Added and Last seen values for paired clients while keeping unknown timestamps truthful for legacy records
- Hardened canonical X.509 client identity, revocation, duplicate-state validation, and authenticated request-time authorization snapshots
- Hardened paired-client persistence with private, cross-process atomic state replacement
- Improved paired-client controls so failed mutations remain visible instead of reporting false success in the web console
v1.3.0 - 2026-07-11
Section titled “v1.3.0 - 2026-07-11”Feature release focused on self-service stream diagnostics, safer release visibility, display planning, and more resilient Linux capture startup.
- Added a manual Update Center with release metadata, package guidance, and a visible update call to action in the web console
- Added deterministic Polaris Doctor diagnostics and privacy-safe support reports for host readiness, active streams, and post-session troubleshooting
- Added optional AI Doctor explanations that translate deterministic findings without replacing the local-first diagnostic source of truth
- Added native network-path probes for route, latency, packet-loss, and reachability evidence in support workflows
- Added native controller, isolation, and haptics diagnostics so input-path failures can be separated from client or game behavior
- Added a display resolution planner that explains requested, host, capture, and output-mode compatibility before launch
- Expanded Mission Control and Troubleshooting self-tests, support bundles, and issue-draft generation with clearer remediation steps
- Improved Linux desktop capture startup by self-healing stale Wayland, display, and session-bus environment values
- Hardened headless DMA-BUF capture so conversion failures fall back cleanly instead of leaving private streams stranded
- Clarified NVIDIA, AMD/VAAPI, GPU-native, and fallback guidance across the public setup and troubleshooting docs
v1.2.1 - 2026-07-10
Section titled “v1.2.1 - 2026-07-10”Patch release focused on CachyOS/Arch Settings reliability, Linux audio/capture diagnostics, and safer Moonlight-compatible host troubleshooting.
- Fixed Settings saves being blocked by an internal SteamGridDB clear-key flag, allowing unrelated Network and trusted-subnet changes to save normally
- Improved Settings pending-change handling so cancelled SteamGridDB key clears no longer reappear as phantom unsaved edits
- Added clearer backend error details for failed Settings saves so support can identify rejected config keys instead of treating every failure like a filesystem permission issue
- Improved PipeWire audio overrun diagnostics so stream support bundles and logs better explain audio-path failures during launch/connect attempts
- Clarified GPU-native Stream relaunch/fallback reporting for Linux hosts, including AMD/VAAPI SHM fallback messaging and vendor-neutral capture diagnostics
- Hardened Linux private/windowed compositor capture policy so cage/labwc runtime probes happen against the intended streaming runtime instead of a missing display context
- Refreshed public docs, screenshots, and install guidance for Moonlight-compatible users arriving through Fedora, Arch/CachyOS, Ubuntu, and Bazzite paths
v1.2.0 - 2026-07-03
Section titled “v1.2.0 - 2026-07-03”Feature release focused on Nova-ready private/headless streaming, Portable Chrome cockpit polish, safer launch contracts, Linux input/capture hardening, and broader package coverage.
- Added the Portable Chrome web theme with a dimmer Moonlight-grey early-2000s retro-futurist skin, stronger chrome panel depth, restrained green status accents, and generic theme-toggle cycling across every registered skin
- Improved npm run smoke:web so release smoke gates can target live Polaris or built static web assets, check hashed JS/CSS assets plus the unauthenticated login page, and report a clear preflight when the live HTTPS server is not running
- Added a guided AI Auto Quality optimizer setup checklist with clearer provider/auth/runtime cards and actionable draft test feedback
- Polished release accessibility/mobile readiness with named icon controls, live status regions, trapped confirmation-dialog focus, and non-sticky handheld review bars
- Polished Mission Control live-session hierarchy with a stronger top summary for stream quality, latency, FPS, loss, bitrate, capture path, and runtime mode plus collapsible secondary live panels
- Added a sticky Library import staging summary and review drawer with source counts, per-game removal, clear-all staging, and already-imported confirmation
- Reduced idle web console polling pressure by deduplicating overlapping system/stream stats fetches and backing off transient fallback failures
- Added a Settings pending-changes review drawer with safe before/after values, save/apply impact labels, jump links, and per-setting reset controls
- Added confirmation dialogs and async toast feedback for host-affecting web actions such as disconnecting clients, recovery controls, stale display cleanup, and restart-sensitive quick toggles
- Hardened Linux lock-screen dismissal so a failed loginctl unlock-session attempt continues through other graphical user sessions before falling back to loginctl unlock-sessions
- Added Polaris v1 client/session surfaces for Nova: client settings advertisement, session status/stop integration, stream event queueing, and paired-client launch/input permission hardening
- Hardened private/headless launch policy around desktop Steam, mirror-desktop intent, strict gamepad isolation, host virtual-gamepad metadata, and headless bwrap setup
- Improved NVIDIA/Linux capture contracts with CUDA/GPU-native capability checks, DMA-BUF fallback diagnostics, virtual display output preservation, and headless VAAPI capture reinitialization
- Added openSUSE Tumbleweed build coverage and refreshed package/release workflows for the current Fedora, Ubuntu, and Arch asset line
v1.1.0
Section titled “v1.1.0”Feature release focused on the Polaris web console, Library workflows, safer pairing defaults, and NVENC split-frame hardening.
- Polished Mission Control degraded-state handling and Library management flows so active sessions, imports, and app editing are easier to scan and manage
- Renamed Auto Quality UI surfaces toward clearer stream-profile language
- Added a server-authoritative
Game Controlpairing access preset for QR/OTP and manual PIN pairing, granting list/view/launch plus input permissions without clipboard, file transfer, or server-command access - Labeled paired clients with the exact Game Control permission mask as
Game Controlinstead ofCustom Access - Hardened NVENC split-frame defaults by explicitly passing FFmpeg’s disabled split-frame value when split-frame encoding is disabled
- Improved Linux lock-screen dismissal so Polaris falls back from a systemd manager session to the graphical login session before running
loginctl unlock-session - Added web, pairing, and video regression coverage for the new access preset and split-frame default behavior
v1.0.18
Section titled “v1.0.18”Hotfix release focused on keeping cached AI launch profiles from forcing capable clients back to 720p.
- Bounded cached AI display-mode optimization by the explicit client request so Shield, Retroid, and Android TV launches that request 1080p keep a 1080p headless compositor
- Preserved history-safe recovery behavior so confirmed recovery profiles can still lower resolution or FPS when a recent session needs it
- Smoke-tested a Shield direct Steam launch with Nova
v1.0.10, confirming the client request, Polaris-selected mode, labwc headless runtime, and Android decoder all used1920x1080x60
v1.0.17
Section titled “v1.0.17”Hotfix release focused on session lifecycle cleanup after client End and terminate flows.
- Cleared stale paused/resumable session state when an app is explicitly terminated after the last stream client disconnects
- Emitted a terminal
stream_endedlifecycle event from the terminate cleanup path so Nova can remove stale Active Session/Resume UI - Made the session shutdown-request flag thread-safe between HTTPS controls and stream cleanup
- Added regression coverage for paused app termination, connected-client guards, duplicate idle suppression, and streaming cleanup handoff
v1.0.16
Section titled “v1.0.16”Stability hotfix release focused on client certificate verification during reconnect and disconnect flows.
- Fixed a crash in HTTPS client certificate verification by giving each verification request its own OpenSSL
X509_STORE_CTX - Protected paired-client certificate state while concurrent HTTPS threads verify Nova/Moonlight clients
- Added regression coverage for concurrent certificate verification against the pairing certificate chain
- Rebuilt local master with CUDA enabled and smoke-tested a Retroid Pocket 6 direct Steam launch through headless labwc, DMA-BUF GPU capture, CUDA conversion, and NVENC
- Confirmed the direct Retroid launch path stayed clear of inherited MangoHud and cleaned up the isolated session without a new coredump
v1.0.15
Section titled “v1.0.15”Hotfix release focused on keeping MangoHud out of Linux headless stream runtimes unless a game explicitly opts in.
- Suppressed inherited and session-pacing MangoHud injection for direct Steam game launches inside the headless cage compositor
- Kept explicit per-game MangoHud support available for direct game launches while continuing to block MangoHud for Steam Big Picture sessions
- Cleared
MANGOHUD_CONFIGfrom the isolatedlabwcand XWayland runtime so compositor/helper processes do not inherit stale FPS-cap configuration - Added policy coverage for direct headless cage launches and Steam Big Picture suppression
- Smoke-tested a direct Retroid Pocket 6 launch under a forced parent
MANGOHUD=1environment and verified stream child processes did not retainMANGOHUD*
v1.0.14
Section titled “v1.0.14”Patch release focused on Steam launch reliability, encoder/runtime polish, and safer Linux capture setup.
- Improved Steam library launch behavior, including direct Steam launch mode and non-default Steam library discovery
- Added NVIDIA NVENC split-frame encoding support, prepared FFmpeg wiring, configuration validation, and user-facing docs
- Improved Auto Quality and Adaptive Bitrate behavior so paired-client bitrate, recovery profiles, and clamp edge cases are handled more safely
- Added AMD GPU telemetry support and clearer dashboard handling for optional vendor-specific metrics
- Improved Linux unlock fallback, session cleanup, AMD headless DMA-BUF handling, and runtime diagnostics
- Added safe local development cleanup tooling with script coverage and building-guide documentation
- Hardened display selection so capture setup handles empty display lists without clamping against an invalid range
v1.0.13
Section titled “v1.0.13”Patch release focused on AI Auto Quality, Nova coordination, and Linux stream pacing diagnostics.
- Added richer Nova/Polaris settings sync so launch optimization, applied stream settings, presentation state, adaptive bitrate status, and optimizer health are visible across both sides
- Merged adaptive bitrate behavior into the AI Auto Quality path so recovery decisions can consider network pressure, host frame pacing, encode pressure, and session history together
- Improved AI optimizer feedback handling so short low-confidence sessions do not incorrectly relax safe FPS caps or poison game profiles
- Added safer history-based recovery profiles, including FPS fallback behavior and clearer host-render-limited session grading
- Improved Linux headless stream reporting for DMA-BUF capture, CUDA conversion, encoder target, frame residency, and SHM/CPU fallback reasons
- Added resumable disconnect handling and cleanup improvements for Steam and isolated cage sessions
- Expanded optimizer, adaptive bitrate, stream stats, process migration, and web UI coverage for the new Auto Quality flow
v1.0.12
Section titled “v1.0.12”Patch release focused on corrected Fedora/Bazzite NVIDIA release assets.
- Rebuilt Fedora 42, Fedora 43, and Fedora 44 release RPMs with CUDA enabled so NVIDIA/NVENC hosts can use the validated GPU-native upload path
- Added release validation that fails Fedora RPM packaging if a tagged release reports
Build features: cuda=disabled - Normalized the Fedora CUDA toolkit header patching flow for CUDA 13.2 headers and Fedora 42/43/44 release builds
- Fixed release dispatch packaging dependencies and Arch release validation so patch-release asset rebuilds are repeatable
- Kept the v1.0.11 Browser Stream and Linux runtime diagnostics behavior otherwise unchanged
v1.0.11
Section titled “v1.0.11”Patch release focused on Browser Stream validation and Linux stream-runtime polish.
- Added experimental Browser Stream using WebTransport and WebCodecs, with
/browser-streamrouting and/webrtccompatibility aliases - Added the Polaris-launched WebTransport helper, browser session API, WebCodecs playback, and browser keyboard, pointer, wheel, and touch input routing
- Added Browser Stream UI modes for Game Mode, in-game expansion, pop-out streaming, stream profiles, latency statistics, and unsupported-browser messaging
- Improved Linux stream runtime diagnostics, stream display policy reporting, and GPU-native/headless capture path explanations
- Improved Linux launcher integration, labwc refresh-rate handling, headless preview diagnostics, and stream cleanup behavior
- Fixed Browser Stream close handling so the helper, transport, cage runtime, and launched Steam game are cleaned up together
- Fixed Steam handoff after Browser Stream cleanup so Nova/Moonlight launches are not blocked by stale Steam child processes
- Fixed isolated Linux audio routing so game audio streams that move back to the host sink are returned to the Polaris virtual stream sink
- Added isolated Linux process cleanup for Steam-launched children that escape the direct app process group
- Fixed SHM capture color handling for reported wlgrab pixel formats and expanded unit coverage for the copy path
- Tightened HDR metadata gating, web config save behavior, and Browser Stream route/config/status test coverage
v1.0.10
Section titled “v1.0.10”Patch release focused on Linux streaming diagnostics and host-session isolation.
- Gate true HDR streaming on display HDR metadata instead of client dynamic-range requests alone
- Add Linux true HDR diagnostics to logs, session status, and support data
- Document the KMS/DRM HDR validation path and current headless labwc SDR behavior
- Fixed Linux shader runtime path packaging so packaged builds can find shader assets correctly
- Isolated Linux headless audio routing so Polaris can capture its virtual stream sink without leaving the host desktop default sink redirected
- Added troubleshooting notes for Linux headless audio routing and HDR metadata validation
v1.0.9
Section titled “v1.0.9”Patch release focused on Linux headless color correctness and support clarity.
- Fixed AMD/Mesa true-headless SHM color channel handling for reported 3bpp and 4bpp formats
- Prevented the first-run welcome wizard from staying on
Saving...when browser-side credential saving fails - Clarified Headless Stream vs Desktop Display behavior on Linux
- Clarified current Linux HDR/Main10 limits and the recommended SDR VAAPI validation path
- Documented that Polaris can be installed alongside Sunshine, but both hosts should not run on the same default GameStream ports at the same time
- Clarified that Moonlight is not inherently capped to 60 FPS; Polaris respects the FPS explicitly requested by the client
v1.0.8
Section titled “v1.0.8”Patch release focused on Bazzite headless stream validation and host-session isolation.
- Fixed Linux EVDI virtual display output detection when Polaris opens a pre-created EVDI DRM card
- Documented the Bazzite EVDI
initial_device_count=1setup path for virtual display validation - Replaced the Bazzite service override heredoc with a
systemctl --user edit --stdincommand and documented the validated headless labwc success markers - Clarified the recommended Bazzite Headless Stream optimization, expected SHM/RAM capture warnings, and host-input isolation success markers
- Routed headless labwc virtual input through the labwc socket and blocked host uinput fallback when the headless runtime is active
- Cleared host
DISPLAYfrom cage-launched app and Steam follow-up commands so launched processes stay inside the stream runtime
v1.0.7
Section titled “v1.0.7”Patch release focused on the first-run credential wizard.
- Documented the Bazzite composefs workaround for KMS capture: copy Polaris to
/usr/local/bin/polaris-kms, applysetcapthere, and run the user service from that writable copy - Prevented the first-run credential wizard from staying on
Saving...forever when the browser-side password request fails
v1.0.6
Section titled “v1.0.6”Patch release focused on first-run Bazzite setup clarity and web credential routing.
- Redirect first-run
/loginand/recovervisits to the welcome wizard when no web credentials exist - Clarified first-run setup URLs in the README and Bazzite guide
- Updated the Bazzite guide to run
sudo polaris --setup-host --enable-kmsfor the DRM/KMS capture path
v1.0.5
Section titled “v1.0.5”Patch release focused on cleaner Bazzite/Fedora 44 packaging and headless runtime dependency coverage.
- Added the Linux headless runtime helpers to package dependencies:
labwc,wlr-randr, Xwayland, andxdpyinfo/x11-utils - Avoided GPU DMA-BUF capture when the build lacks a matching GPU upload path, preventing invalid CPU frame conversion in headless labwc sessions
- Added Fedora 44 RPM release assets for Bazzite 44 and Fedora 44 users
- Simplified the Bazzite install guide around one matching Fedora RPM layered through
rpm-ostree
v1.0.4
Section titled “v1.0.4”Patch release focused on Bazzite tester feedback and credential recovery.
Highlights:
- Fixed BGR0 CPU-frame conversion fallback by inferring packed row stride when capture reports
row_pitch = 0 - Prevented headless
labwcfallback paths from failing encode conversion withsrc_stride=0 - Updated the Bazzite guide with
labwc/wlr-randrlayering, Desktop Mode-first validation, and known log-message guidance - Marked Bazzite and Ubuntu package paths as extremely experimental tester paths until broader real-hardware validation is complete
- Clarified web credential recovery: run
polaris --credsas the same user, restart Polaris afterwards, and avoid shell-confusing placeholder commands
v1.0.3
Section titled “v1.0.3”Highlights:
- Added an experimental Bazzite install path using the Fedora RPM through
rpm-ostree - Added a Bazzite validation checklist for desktop mode, gamemode, GPU, pairing, and headless behavior
- Added Ubuntu 24.04 DEB packaging:
Polaris-ubuntu24.04-x86_64.deb - Added an Ubuntu install guide with package, source-build fallback, and validation notes
- Polaris config saves now stay isolated from legacy Sunshine config paths
v1.0.2
Section titled “v1.0.2”Patch release focused on validated Linux release packages.
Highlights:
- Fedora 42 and Fedora 43 RPMs now build with package-style install paths under
/usr - Fedora RPM smoke tests install the generated RPM, verify the packaged binary, and check shared-library resolution
- Fedora 43 is now part of the official release asset validation matrix
- Arch package validation now checks the package against the current distro Boost runtime before release upload
- Public install docs were refreshed for Fedora 43 and current Arch package dependency behavior
v1.0.1
Section titled “v1.0.1”Patch release focused on dual-distro packaging, Linux runtime hardening, and public web-console polish.
Highlights:
- Arch joins Fedora as a first-class GitHub release package target, with refreshed
v1.0.1assets for both distro paths - Headless
labwcstartup, preview routing, and Mission Control preview-source labeling are improved - Mission Control charting is split out and the web shell is hardened against local self-signed HTTPS chunk-load failures
- The web console now pauses polling and live telemetry while hidden, reducing idle browser and host load
- Browser smoke coverage now checks the key public routes against a live Polaris instance
- Trusted Pair diagnostics and trusted-subnet matching are clearer, including IPv6 support
- Client-requested display modes now cap AI/session optimization upshifts instead of being silently exceeded
- Control-shell AI cache handling is less noisy for Steam UI and desktop-style sessions
v1.0.0
Section titled “v1.0.0”First public Polaris release.
Highlights:
- Linux-first host with a dedicated streaming compositor path
- Web UI for Mission Control, library management, pairing, settings, security, and troubleshooting
- Trusted Pair, QR pairing, and manual PIN pairing flows
- Live session preview, runtime telemetry, diagnostics, and quick controls
- Steam, Lutris, and Heroic library import flows
- Nova-aware launch modes, watch mode, and richer session-state integration
- Adaptive bitrate, AI optimizer support, and per-title tuning
Release assets
Section titled “Release assets”Current official public assets:
Polaris-fedora44-x86_64.rpmPolaris-ubuntu24.04-x86_64.debPolaris-arch-x86_64.pkg.tar.zst