July 29, 2026
38 public commits · 4 public repos · 383 private commits
- Private work 6 repos sealed
383 commits and 1 forge event count toward the day. Names, subjects, and links stay private.
- Pixel3Arch 14 changes
- 11:21 p.m. · daa9d37
Everything in pkgs/ has been hand-built on [host] and installed with pacman -U, which is invisible to -Syu and to souveraine-updater -- it groups by the repo a package came from (updater-core/src/pacman.rs:442), so a hand-installed package is never offered as an update whatever it is named. TASK-25.
- 10:39 p.m. · 7647ff6
Every routing decision the device makes lives in these three files and none of them was owned by a package -- they were hand-copied from rootfs-overlay, which is the failure mode TASK-25 exists to end. alsa-ucm-conf ships nothing for this board, so there is no file conflict.
- 10:31 p.m. · 8417a2c
The 'structurally dead on this card' line was wrong and cost real time: ACP never probes hw:0,2, it probes the PCMs the verb declares. Records the five defects, the one-backend-per-front-end rule, and why the earpiece/speaker toggle cannot live in callaudiod here.
- 10:28 p.m. · f954b73
Moves a live call between the loudspeaker and the earpiece by writing the two amps directly. Not through alsaucm: enabling a UCM device from a one-shot process means setting the verb first, and re-running the verb EnableSequence mid-call would re-poke the Q6 voice mixers under a live session.
- 10:16 p.m. · 3d6f6ec
Calls came out of the loudspeaker with no way back, because the verb had one device named Speaker that carried both directions. callaudiod toggles speakerphone by selecting a sink port (cad-pulse.c:961) and matches ports by type, skipping any card without both a speaker and an earpiece port (:495).
- 10:00 p.m. · e2c2e15
tinyalsa's pcm_open() returns a non-NULL handle even when the open failed, and q6voiced_open() stores it before checking, behind an "if (v->tx) return" guard. One failed open therefore silences the whole call.
- 10:00 p.m. · 4e5dfb5
The unmap list now covers the QUAT voice mixer and puts MultiMedia1 back on the amps, since a front-end takes one backend and losing it leaves the speakers dead.
- 10:00 p.m. · eb48b7a
Three defects, all of which had to be fixed before a call could carry audio both ways:
- 6:46 p.m. · b9b2cc5
alsaucm keeps its UCM context in-process, so a one-shot `set _verb` has no previous verb to dismantle and never runs its DisableSequence. TX5 (HiFi) and TX7 (VoiceCall) both stayed mapped into AIF1_CAP across a call; SLIM_0_TX then carried two channels into a mono front-end and hw:0,1 read exact zeros. The microphone was dead after every call until TX7 was cleared by hand.
- 1:57 p.m. · 0bf4cbd
First real call, 2026-07-29: the call terminated at 13:48:40 and ModemManager did not emit CallDeleted until 13:49:11. For those 31s every stream on the device stayed routed into the modem.
- 1:36 p.m. · 796308a
The hook and its unit shipped only via rootfs-overlay, so no package owned them and /etc/systemd/system shadowed anything packaged later.
- 9:13 a.m. · cd8b67e
squeekboard sat at extra's exact version, 1.43.1-5, and stevia sat above it, pkgrel 9 against 1. Both positions are bad: equal means pacman cannot tell our fixed build from the broken one it replaces, which is what stranded the /usr/local regression fix; above means a real upstream bump is hidden forever. Under our own names the version is ours. provides/conflicts/replaces take over from the IgnorePkg entry, which stops being load-bearing.
- 9:00 a.m. · 230d7dd
Nothing on this device starts graphical-session.target — greetd runs Hyprland directly and hyprland.lua starts units by name, and this one is not in that list. So the producer was `enabled` and dead from every boot. It ran on 07-28 only because a session started it by hand; that instance was stopped at 21:40:52 and nothing brought it back, which is why grip "stopped working".
- 8:34 a.m. · 87efdd0
Dropping arch-meson (it injects host -march/-mtune) also dropped the --prefix=/usr it supplies, so meson used its default /usr/local. All 39 files shipped there: ExecStart=/usr/bin/squeekboard failed 203/EXEC, and the GSettings schema landed where glib never looks, so the paths that did reach the binary died on g_error. Regression from the 2026-07-27 rebuild that went out as 1.43.1-5; 1.43.1-1 shipped usr/bin correctly.
- 11:21 p.m. · daa9d37
- souveraine 11 changes
- 6:13 p.m. · 147f7f2
The masked-fullscreen version was completely untappable on device. Rather than keep guessing at the mask, the window is now sized to the card and moved by margins, so every pixel of it is the chip. Also stops an invisible fullscreen surface sitting over the app's own selection UI.
- 6:05 p.m. · 5a643d7
Two bugs from the first on-device run.
- 5:54 p.m. · 808f063
Deployed and verified on blueline: watcher starts, a selection settles with an anchor, and the lock gate kills the watcher.
- 5:47 p.m. · 0bebc77
Overlay layer following DialHost, keyboardFocus None throughout, and an input mask limited to the card so taps elsewhere reach the app underneath. Anchors to the pointer hint above the touch point, clamped on screen.
- 5:25 p.m. · 147999a
Verified on blueline that Hyprland advertises primary-selection plus both data-control managers, so wl-paste --primary --watch sees every selection with no per-app hooks. Settles TASK-18's selection-detection question as compositor-level; viewtop is not needed.
- 11:37 a.m. · c8507e9
It authenticated through PAM, called unlock_and_destroy(), and returned Unlocked — and then the shell, whose GlobalStates.screenLocked is a separate bool, re-registered, was told must_lock=true, and locked again. The protocol has a lock directive and no unlock directive, so the fallback could open the compositor's lock and had no way to tell the session it had. Casey hit it exactly that way: "it logs in, and then qs says Locked still."
- 10:54 a.m. · 0a635ff
bootBloomActive defaults true on every scene construction and bootDismissed resets with it, but the only thing that cleared them was the secure EDGE. A scene reload during an already-secure lock never moves `secure`, so nothing cleared the bloom and the phone sat under a full-screen white overlay until the shell was restarted. Casey hit it and reported it as "the hyprland error screen"; `grim` returned a solid white 9KB frame, and hyprctl configerrors was empty the whole time.
- 10:43 a.m. · 45fbbea
A scene reload re-runs SessiondBridge while the outgoing connection is still open, so the reload's shell_ready races its own predecessor's EOF and sessiond refuses it — correctly, since the lease is genuinely held. The bug was the shell then giving up for good: it read the refusal as "another shell owns the lease, we are not the authority", cleared nothing, and left registerRetry idle. A second later that EOF landed, shell_alive dropped, and sessiond spent the rest of the session believing there was no shell — while a live one sat on a connected socket.
- 9:14 a.m. · de64480
- 8:39 a.m. · 8db55cf
It existed only in [host]'s checkout — never added, not gitignored, absent from the laptop. Two sections had gone stale against the code and are corrected in the same change: modules/ is no longer "coming", and deploy.sh composes the whole config rather than swapping Ai.qml.
- 8:27 a.m. · 5965c64
~/souveraine-surfaces/quickshell on the phone is not a git repo and was the only copy of five files. Brought back verbatim:
- 6:13 p.m. · 147f7f2
- SouveraineOS 9 changes
- 6:17 p.m. · d811870
- 5:55 p.m. · 39c9a02
Folds in the 2026-07-29 finding instead of a new task file; TASK-32 already owns how these surfaces ship.
- 5:48 p.m. · 00d2449
deploy.sh:246 rsyncs --delete into the phone's surface tree with no snapshot, unlike the local compose which snapshots to .ii-previous. Root cause is installing into $HOME, which has no file-ownership model. Payload belongs in /usr/share owned by a package; $HOME keeps only overrides.
- 11:57 a.m. · aef29b8
- 11:57 a.m. · 38c9be0
- 10:45 a.m. · 85b172a
- 8:46 a.m. · e421975
- 8:28 a.m. · 1628915
- 6:38 a.m. · daad100
- souveraine-speech 4 changes
- 4:51 p.m. · a766683
chatterbox-ttsd is disabled. The phone points at :7863 in config.toml and the shell config.json and speaks the old {input,voice,model} contract, so tts-compat.py translates it to the OpenAI shape on :7865. Any voice name maps to annie, matching the old fallback-rather-than-400 behaviour.
- 4:49 p.m. · 02d2dd9
Replaces chatterbox for the dashboard. RTF 1.0 vs 3.36, first audio 0.33s vs 43s, so progressive playback works. Runs on :7865; chatterbox stays on :7863 until the phone is repointed. Voice registry is in-memory, so the unit re-registers on start.
- 3:44 p.m. · 19c0e30
The chunking duplicated tts-cli's own --max-sentence-chars splitting, which already crossfades its segments; ours re-ran the process per chunk and joined separately-encoded mp3s with no crossfade. Reverted.
- 2:16 p.m. · 48b5caa
tts-cli is one-shot, so a paragraph meant minutes before the first byte. Split on sentence boundaries and send each piece as it finishes via chunked transfer. 499 chars: first audio at 43s instead of 167s.
- 4:51 p.m. · a766683