Skip to main content
0.12.0 produced no downloadable Flatpak. This fixes that, corrects something 0.12.0’s notes stated as fact, and reports a measurement that closes a gap those notes left open.

The Flatpak release attached nothing

0.12.0’s Flatpak bundle built correctly and was never attached, because the job died two steps later assembling the GitHub Pages tree:
The commit that renamed the two README banners out of packaging/icons/ — so they would stop being mistaken for the application icons — updated the README, both PKGBUILDs, the rpm spec and the Flatpak manifest, and missed one line in the workflow. The banner is referenced nowhere else in the tree, so nothing else failed and it looked like a Flatpak problem rather than a missing file. It had been failing on every push since, not only on the release. The square application icon on the line above it was never affected; packaging/icons/hicolor/scalable/apps/ still holds it and the Frostbite variant.

Correction: there is no PR_SET_PDEATHSIG

0.12.0’s notes said the plugin sandbox is started with --new-session, --die-with-parent and PR_SET_PDEATHSIG. The last of those does not exist. sandbox.rs passes --unshare-all, --die-with-parent and --new-session, and there is no prctl call anywhere in Cordial’s own code that sets a parent death signal. The 0.12.0 notes have been corrected in the repository. This matters beyond pedantry: the two were described as belts to each other’s braces, and they are not. There is one mechanism, and it turns out to be the one that does all the work.

The signal case is now measured, and it holds

0.12.0 said plainly that Drop cannot run when the client dies by signal and that nobody had established whether the sandbox flags covered what Drop could not. They do. Twelve trials — SIGKILL, SIGABRT, SIGSEGV and SIGBUS, three each, signalling the parent and never bwrap — left no survivors. The control is a measured one rather than a historical baseline: the same twelve signals with --die-with-parent and --new-session stripped from the sandbox’s argv leaked every process, every time. Isolating the two flags on SIGKILL: --die-with-parent alone leaves no survivors, and --new-session alone leaves all three. --die-with-parent is what covers the signal path. --new-session earns its place on the ordinary teardown path instead, where it is what lets Drop’s kill(-pid, SIGKILL) reach the whole group.

A plugin cannot spawn a subprocess at all

The other open question was whether a plugin’s own grandchild could outlive both Cordial and bwrap, since bwrap forks internally. It cannot arise: sandbox.rs passes no --allow-* flags, so a plugin calling Deno.Command(...).spawn() gets NotCapable: Requires run access. Probed anyway with a deliberately constructed four-deep tree under the same flags — bwrap, bwrap, deno and a detached sleep — the cascade still reached all of it, no survivors against a control that leaked everything. The mechanism covers a grandchild that the permission model does not currently permit to exist.

What is still broken

Everything 0.12.0 listed, unchanged: the startup freeze when signed in, the black canvas inside an experience, the second half of the CachyOS crash, and the web-view dialog cursor. The dialog cursor has one more thing known about it, and it is not encouraging for anyone hoping to test it: the development control surface cannot exercise that code path. Its click and move verbs call the engine’s input entry points directly, while the check that withholds a click from the engine lives in the Wayland pointer listener, which only fires for real compositor seat events. A scripted click therefore always reaches the engine whether or not a dialog is up. Confirming this bug needs a real pointer.

/ opening chat on one press is now verified

0.12.0 shipped this fix and said plainly that nobody had driven a real / at a real chat box. Somebody now has, against a joined experience under a nested sway with a real virtual keyboard held open. Eight attempts, each engineered as the worst case — the release sent only after the engine already reported the box focused, which is the exact race the bug lived in. None showed the pre-fix signature. Seven of eight opened chat on the single press and printed the fix’s own marker. The eighth did not settle within the harness’s poll and is attributed to the harness’s own reset issuing a redundant Escape; it is recorded rather than explained away. No stray character, which was the thing worth doubting: chars=0 on all eight. And Sober #987 is intact. Typing / into an already-open chat box suppresses both the press and the release, puts the character in the box, and leaves the focus generation unchanged — chat does not retrigger. Two things the harness had to get right first, both worth knowing. Chat does not exist at the Home screen; it is a feature of a joined experience, so a test that never joins measures nothing. And the control surface’s text verb cannot type punctuation at all — see NEXT.md — so / sent that way never reaches pass_key_event, which would have produced a confident and completely false pass.