Do-not-disturb on every device¶
One do-not-disturb for all your devices: turned on or off on any of them, it holds on all, each silencing its own system as far as the system lets an application do it; one list of the people who may reach you then, kept in the sharing itself; and the phone kept in step in the background. Code: crates/sioul-core/src/everywhere.rs (the rules), crates/sioul-app/src/everywhere.rs (applying and saying it), crates/sioul-app/src/steps.rs and android/package/src/com/aurelienpierre/sioul/StepService.java (the phone in the background); the systems' own do-not-disturb is the layer of pauses.md (crates/sioul-app/src/dnd.rs).
The owner's words: "a global, cross-device do-not-disturb mode that communicates through the shared vaults between all instances of the app, and allows for example to turn the phone's DnD on or off from the desktop when in a task, with unified contacts management for the people allowed to go through the DnD mode across devices […] handled through phone calls, SMS and email."
Why it holds¶
Do-not-disturb holds while one of its reasons does. Each reason is read from the one place that already says it, and that place is shared as it is: every device reads the same files and comes to the same answer, and nothing is said twice.
| Reason | Read from (part of the sharing) | Setting ([dnd]) |
Ends |
|---|---|---|---|
| the pause | quiet.toml, paused_since/paused_ended (time) |
pauses, on |
when you come back |
| Free time | quiet.toml, free_since/free_ended (time); never with the pause |
pauses, on |
when you come back, at the night's start |
| sleep | Health's night and naps (health), on each device's clock | sleep, off |
at waking |
| focus | time/running.toml (time): a session counting, not paused |
focus, off |
30 minutes past the time chosen, three hours without one |
| the switch | state/do-not-disturb.toml (settings) |
button, on: the switch shows |
when you turn it off, or at the end you chose |
- The latest change wins, the switch against the reasons too: the switch pressed off after a reason began holds that reason off until it ends; a reason that begins after the press holds again (the next focus session, the next night). A press "on" never holds a reason off. Pressed off during a pause, the switch lifts only the system's do-not-disturb: the pause still holds Sioul's own notifications.
- A focus session forgotten never keeps you unreachable for long: it holds do-not-disturb until 30 minutes past the time chosen, three hours for a session without one (
FOCUS_GRACE,FOCUS_OPEN). - Said first: the pause, Free time, sleep, focus, the switch. The end said is that of every reason that holds, when each has one; a focus session's limit is never said (it is no promise).
-
Its modes: the pause and Free time keep their own (pauses.md); sleep, focus and the switch share a third, "Do not disturb (Sioul)" (
dnd::Which::Global). Each lets through what the matrix of what reaches you lets through then (attention.md, §3.3:Attention::silenceat the pause's column, Free time's with its "Nothing at all", and for the third the strictest of Sleep's and Do not disturb's that hold), as far as each system can say it. On a phone (android.md):Through the mode When Calls from your contacts the phone screens calls, and the matrix lets someone known or Always through call then (the screening declined the others before the phone rang) Calls from anyone the phone screens calls, and the matrix lets strangers or hidden numbers call then Calls from starred contacts the phone does not screen calls, and the matrix lets anyone call then Messages from starred contacts the matrix lets anyone write then (never more: Android rings before Sioul's listener can hold, and the mode is what keeps a held message silent) A second call within 15 minutes whenever calls get through Priority conversations (Android 11 and later) the Always through row of Messages lets them come then: the conversations set to Always through, marked Priority in Android Alarms always Dose reminders, an event's alarms the matrix lets them come then, each in a channel of its own that passes ("Doses during a pause", "An event's alarms during a pause") New mail from someone Always through told then, in its own channel that passes ("New mail from people always let through") With the usual matrix every mode lets through Always through (their calls as the screening lets them ring; the starred's messages; priority conversations), a second call, alarms, doses and an event's alarms (in sleep and Free time, when its event falls then); Free time lets your safe people call too, but with "Nothing at all". Each mode's policy is worked out again at each apply (the minute's, a press, an exchange), and the mode brought up to date when it changed.
The switch, shared¶
state/do-not-disturb.toml, in the settings part: the one part every device shares, where the triggers' own settings travel ([dnd] in config.toml). One table per device, written by that device alone and shared whole (whole = ["device.*"]): two devices never fight over one entry in the sharing's later-wins, and the merge is Sioul's own, in code.
[device."<the device's id in the sharing>"]
kind = "phone" # or "computer"
name = "" # a computer's host name
pressed = 1759760000000 # its last press of the switch (milliseconds, a hybrid clock)
on = true # what that press asked: do-not-disturb on (false for As usual and Reachable)
mode = "dnd" # which of the three states it asked: "reachable", "usual", "dnd" (absent: read by `on`)
until = 1759765400000 # the end chosen with it; 0: until turned off
open = true # Reachable "until you turn it off" (its end the night's start, or waking)
release = 1759760000000 # the last "Let what your phone holds through" pressed here (hybrid clock)
seen = 1759754000000 # the latest press of another device known here then
why = "manual" # what holds here now, as this device reads the reasons
silenced = true # its system's do-not-disturb is on for it
line = "…" # its system's answer, in its words
at = 1759760000000 # when this table was written
via = "system" # its last press came from its own do-not-disturb (absent: the switch)
turned_off = true # while it holds: its own do-not-disturb turned off unheard, left off
system_on = true # while it is off: its system still silenced (`line` says why)
closed = true # Sioul quit on this computer: it follows nothing until it starts again
-
Sioul closed on a computer: as Sioul quits (its window closed, the tray's Quit, SIGTERM, SIGINT, SIGHUP), the computer writes its table as it then holds (
Device::closing:closed,silencedonly for what outlives Sioul, GNOME's switch or a Mac's Focus, Plasma's inhibitions ending with it), sent by the last exchange; the other devices say "On laptop: Sioul is closed." (Follows::Closed). A crash writes nothing: a computer said silenced but not heard from for half an hour (COMPUTER_QUIET; a running computer writes its news at least every fifteen minutes) is "waiting for its news". A phone's table holds while Sioul is closed: its modes stay. -
Latest wins, whatever the clocks: a press is stamped after every press already known on that device (a hybrid clock: the later of now and the latest stamp seen, plus one), so a press made after seeing another comes after it even when the clocks disagree.
- A margin for clocks that disagree: two presses on two devices that did not know of each other (
seenbefore the other's stamp), less than a minute apart (MARGIN_MS): the quieter state wins, Do not disturb over As usual over Reachable (State's order), but a press that a later press knew of and overrode, which never comes back (three devices: Do not disturb, then Reachable having seen it, then As usual having seen neither, As usual holds; review of part 3, L1); one more press, now seeing the other, settles it. Further apart, the later stamp wins. - The hybrid clock counts the presses and the release stamps known, so that a press made after seeing a release comes after it (F3): a press up to a day ahead of this device's clock (a time zone set wrong), a release up to an hour ahead (
RELEASE_FOLLOWED_MS), so that a release from a clock far ahead never drags the presses along, which would then hold off for hours what begins meanwhile (re-check of part 3, R-3); nothing further ahead is followed (Switch::next_stamp,CLOCK_AHEAD_MS), and no stamp overflows. A press stamped more than a day ahead of the clock that reads it (a garbled stamp, a clock a year ahead) reads as not pressed yet, its Expecting a call too, so that it never wins for ever (Switch::as_of, R-8); once that day is within reach, it comes into force over what was pressed meanwhile, until the next press (C-3). What a clock up to a day ahead costs (decided, check of a23cf0c, C-2): its presses are followed, so every press made after them on any device is stamped as far ahead; an As usual so stamped holds off, until each ends, every reason begun before its stamp, that is a focus session or a night begun in the hours the clock was ahead; Reachable so stamped says it holds from that late; a pause pressed on a device that knew nothing of it does not end it. A clock set right ends it at its next press of any device, as soon as real time passes the stamp. A release from a computer whose clock was ahead is applied once, at the phone's now, and never shadows that computer's later releases (Ledger::applied, C-1). - The end passes on each device by its own clock: no record needed.
- Never written over a file that does not read (half written by hand, damaged): the press fails and says why; the other devices' tables are never written from here.
Applying it¶
everywhere::apply() is the one caller of the do-not-disturb layer: for each of Sioul's three modes, on when its reason holds, off otherwise; the layer does nothing when nothing changed. Called at the window's start and each minute (the pauses' tick), at once on a press, and after an exchange that wrote the switch, quiet.toml, running.toml or the settings. Then this device's table says what holds here and whether its system is silenced, the phone's card is told (homecard::dnd_seen), and on a phone an alarm comes back at the next end (below).
- On Android, only in Sioul's own process, where the layer's modes are kept (
PauseMode's memory): the background service, in a process of its own, asks it throughDndReceiver; so does the alarm of the next end (the switch's end, waking, the next night when sleep counts, Free time's end, a focus session's limit), set exact through Doze after each apply, Sioul closed or not (steps::next). - Where it holds, said by the status line's button of what reaches you, beside the sounds, and in its card What reaches you now (
qml/ReachButton.qml,qml/ReachCard.qml; part 5 of "What reaches you": its three states side by side, each with its lengths, what the phone holds, Mail every minute, the call screening apart; a right click or a long press, Reachable for an hour, Do not disturb for an hour, As usual; the tray's menu offers the same three): "Do not disturb, on every device, until 15:00." when every other device heard from in the last seven days (LIVE_DAYS) holds it with its system silenced, and this one too; "here; your other devices' news is on its way" while every device not silenced yet has simply not been heard from since it began (a device counts only by a table it wrote after do-not-disturb began, a minute's margin for clocks that disagree: its line says "waiting for its news", never what held there before; the news comes at the sharing's pace, about a minute with a Nextcloud server); "here only" when there is no other device, or none can follow; "not on every device" in between; "on your other devices; this one keeps only Sioul's own notifications back" when this device's system cannot be silenced (Windows, a desktop without a way, a phone without the access). Each device's own words are still made (everywhere::moment, itsdetails: "On your phone: silenced.", "On laptop: This computer's notifications cannot be silenced by Sioul: Windows…", "On another device: waiting for its news.", "On laptop: an older Sioul, which cannot follow until it is updated."), as are the last "off" made in a device's own settings and Android's do-not-disturb page (system_line,last_off,here_offers,system_offers): the switch's menu showed them until part 5, and the card does not yet (said tomain, 21 October 2026). The card says why it holds (why_line) and offers Silence this device again. No colour but the accent while it is on. - The switch's menu: Reachable's lengths and As usual (below); on a computer, "Let what your phone holds through"; then, under "Do not disturb", for 30 minutes, an hour, two hours; until what now is for ends (the end of working hours, say); until you turn it off; off, on every device; its settings.
The three states¶
The owner's decisions 6 to 12 of 18 October 2026 (the proposal on what reaches you, §3.1 to §3.3, adopted with all its recommendations): one control holds three states, Reachable (« Joignable »), As usual (« Comme d’habitude ») and Do not disturb (« Ne pas déranger »), shared as the switch is. Pause and Free time keep their own buttons. Code: sioul_core::everywhere::{State, Reach, Length, reachable_until, reachable_end, read_switch, sources_at}, Switch::press_state, Switch::release, Switch::release_stamps; crates/sioul-app/src/everywhere.rs (choose, let_through, moment).
- Written beside
on: a press writesmodewithon; Do not disturb writeson = true, As usual and Reachableon = false, so that an older Sioul reads Reachable as do-not-disturb off. A table withoutmodeis read by itson(Device::state). - Its lengths (decision 8,
reachable_until): 30 minutes, an hour, two hours; until the hours you are in end; until tonight (the night's start, as Health knows it); until you turn it off (open). Every one of them ends by day at the latest at the night's start, at night at waking: a length that meets that end is said with it in the menu ("Reachable for two hours, until 22:30 at the latest"), and the hours' end shown is never past the night's start. Pressed at night, "until tonight" and "until you turn it off" both end at waking, and the menu offers one "until I wake". Without a night known, the menu offers neither, and a press that has no end says so (reach-no-end). - Its latest end, as every reader reads it (
reachable_end; review of part 3, F2): whatever a press says, Reachable ends at its own end, and never past the first night's start after it was pressed by day, the waking of the night it was pressed in, nor a day after it was pressed (REACHABLE_MOST): a press with no end (a later version's, a garbled table) or one a year ahead (a clock gone wrong) holds no night off. - While it lasts (decision 9,
everywhere::now): neither a focus session, nor the night, nor Free time turns do-not-disturb on. Once it ends, what was in force before it comes back (F8): a reason that held when it was pressed holds again, but one that an As usual (or the switch's off) had held off stays held off until it ends, the Reachable press carrying that hold-off (held_off, the As usual's stamp, written besidemode; an older press has none, and holds nothing off past its end). A pause ends it: no Reachable while a pause holds, nor after a pause pressed after it (Sources::pause_pressed), nor after a pause that knew of it, whatever its device's clock said (Overrides::pause_saw, the latest press of the switch known as the pause was pressed; L2). The pause itself refuses it, whatever[dnd] pausessays (F6): the menu does not offer it during a pause, and a press then says so. - What it lets through (decision 7,
attention::Now::reachable): everyone not blocked who writes, by text or by any app, and the people you know who call, at once, whatever the time, its layers and what an address is for; a conversation you set "with the automatons" too (review of part 3, L3); mail of every address, told, the Porch's rest after a pause lifted. Numbers nobody knows and hidden numbers stay the call screening's (attention::screened): with the screening on, as it is set; with it off, they ring as your contacts may, which under Reachable is at every hour (L5). The blocked never; a conversation you set to never stays held (the listener's choice,appnotes::decide). Apps' automatic notifications keep their gathered times. Sioul's own rows (doses, codes, reminders) read as they are. On a device with an older Sioul, none of this: it reads Reachable as do-not-disturb off. - The Porch (decision 7,
backend::follow_reachable): opened at any hour, every lane and address, its rest after a pause lifted, new mail told; the watchers look for mail every minute, as Real time does, until Reachable ends. - The release at the press (decision 7; proposal §3.3): a Reachable press that holds stamps a release (its own
pressed); on a computer, "Let what your phone holds through" writesreleasein that computer's table, a stamp of the hybrid clock, and says that the phone lets it through at its next look. The phone's listener, at its next review (it watchesdo-not-disturb.toml), applies each device's stamps once, apart (appnotes::Ledger::apply_releases,released_byandreleased_throughinapp-notes-seen.toml; F3; a stamp passed over for being more than a day ahead is passed over for good, never applied a day later: R-2): what it first held at or before the stamp comes now (Held::first: held again on its return meanwhile, it is still released), re-snoozed for one second and never cancelled, so that a reply from a computer still finds it; what is held after the stamp is not. A stamp ahead of the phone's clock reads as the phone's now; one more than a day ahead is passed over and said once in the log, and never stands in the way of another device's. Never during a pause (F5): a stamp heard then waits for its end, and applies at the first review after it; the computer's menu does not offer the release meanwhile. The blocked and what is held for good (Never) are never released. Apps' automatic notifications then go back to their gathered times. The computer never learns what the phone held. - The phone's own do-not-disturb both ways: Reachable is do-not-disturb off, so Sioul's modes leave and the phone's own is turned off as for any off ("Both ways", below). The phone's own turned on while Reachable lasts is a press of Do not disturb (
heard), which ends Reachable on every device; turned off, it agrees and presses nothing. - Devices gone from the sharing (review of part 3, F1 and F7): a device the sharing no longer counts is read as an As usual at its last press, and its Expecting a call as "Screen calls again" at its own, nothing more (
Switch::counted): its presses still end what came before them, so that neither a Do not disturb nor an Expecting a call it ended comes back, and it holds nothing off, releases nothing, opens nothing, screens nothing, and is no device that follows (re-check, R-1: the calls' table and the status line's calls read it so too; R-5: a Reachable pressed after its As usual carries nothing of it). The window writes the devices gone, as the sharing's sealed facts say (sioul_sync::share::asking), intogone-devices.jsonbeside the sharing's memory, at most once an hour at its exchanges, never on a dose's path. Every reading of the switch on this device reads them so, and the pauses alike (everywhere::read_switch,everywhere::sources_at): the window, the listener, the calls' table,sioul remind --watch,sioul watchand the MCP. - Read anew at each change: the listener asks Reachable at every notification, kept only while none of its files changed (the switch, the pauses, the devices gone, Health's nights: their times, sizes and inodes) and its end has not passed; the calls' table reads the switch anew whenever it is made, and is made again at the next exchange that brings another device's press (F4).
- "Work now" went (decision 10): Reachable took its people-and-Porch part, and "Work … more" its work part, with Work until tonight (
work_untilat the night's start). Nothing ends any more when Sioul starts or closes (end_work_nowwent). Awork_nowan older Sioul wrote is read as work until its end (quiet::mode), and Pause and its rest still clear it. - "Show all mail now" (decision 12) replaces "Open it anyway", offered whenever the Porch is open: every lane and address, as Reachable shows them (the blocked's mail stays out), on this device alone, until "Done for now"; it tells nothing and makes you reachable by no one.
Both ways¶
The owner's words (7 October 2026): "Yes, do not disturb is a property of an individual, not of a device, so it should be synced across all devices." Each device's own do-not-disturb and the switch mirror each other. Sources: AOSP 12, 15 and 16 (NotificationManagerService, ZenModeHelper, ZenModeConfig, NotificationManager's documentation), plasma-workspace 6.7.5 (libnotificationmanager, the notifications applet's Globals.qml), GNOME Shell (js/ui/status/doNotDisturb.js) and gsettings-desktop-schemas.
- Heard as it happens, whatever caused it (
everywhere::heard_from_system,sioul_core::everywhere::heard): each system's do-not-disturb as one fact, on or off (Android's interruption filter not ALL, Plasma'sInhibited, GNOME'sshow-bannersfalse). A change that disagrees with what holds on that device, once Sioul's own change settled (three seconds) and the state read again, is a press of the switch there (via = "system"): the person's tile or applet, Bedtime, a schedule, a driving mode, another app, Plasma's full screen or mirrored screens. One that agrees is Sioul's own change coming back: nothing. One found later, not heard as it happened (Sioul closed on a computer, a phone still starting), is only said on that device ("turned off here", "… stays on"), never pressed: its time is unknown, and another device may have pressed since. The repeats of one change (a status and a filter, two of Plasma's signals) press once (HEARING).- Android:
DndReceiver, declared in the manifest and not exported, hearsACTION_INTERRUPTION_FILTER_CHANGED, which Android sends every app with Do Not Disturb access, running or not (AOSPNotificationManagerService.sendRegisteredOnlyBroadcast: "explicitly send the broadcast to all DND packages, even if they aren't currently running"), andACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGEDfor Sioul's own modes (ENABLED, DISABLED, REMOVED; ACTIVATED and DEACTIVATED from Android 15, Sioul targeting 36). Both are protected broadcasts.DndHeard.decidedecides in Java: the filter as a change from the state last seen (seen_on; at a restart or an update, the state found then is noted, never pressed, so that the next change counts from it: forgetting it instead, as 0.0.3 did, made the first change after each update or restart a "first sight", never heard; noted too at the first apply when none was ever seen), against Sioul's record (sioul_on, which Rust writes at each apply;on.<kind>); a status only against the mode as Android has it now, so that a late word of Sioul's own update is no press. Before each change of its own,PauseModenotes when it settles (changing_until); a change heard before then is looked at again after it (three looks at most). The library is loaded only for a press (nativeHeard). The notification listener, while bound (whenever Sioul has notification access), hears every change too (AppNotes.onInterruptionFilterChanged, which Android calls on a bound listener at each change of the filter) and forwards it toDndReceiverin Sioul's own process (DndReceiver.HEARD): one change, two words, decided one at a time, the second finding nothing new. Each decision is logged (adb logcat -s sioul: "Do not disturb: the filter heard: on."), nothing of the person's in it. - Plasma:
sioul_sync::dnd::watch_inhibitedfollowsPropertiesChangedofInhibitedfrom the server's owner; a change that held a second is read again (Properties.Get) and told once Sioul's own change settled (quiet, set before eachInhibit,UnInhibitorUntildeleted). A new server (plasmashell started again) is read without telling. - GNOME: dconf's
Notifyofshow-banners(watch_dconf_told), read again withgsettingsa second later, once Sioul's own write settled. - Mac and Windows: not heard. macOS gives an ordinary application no change of the Focus (macOS 26's Shortcuts automations, "When Do Not Disturb is turned off", could call a command of Sioul's: not built); Windows has no documented do-not-disturb for applications (
FocusSessionManagersays only the Clock app's focus sessions).
- Android:
- Off reaches the system (
apply,dnd::system_off): when do-not-disturb goes from on to off on a device (Kept::on_here, kept across restarts), Sioul's modes leave as before, then the system's own do-not-disturb is turned off, once, where Sioul can:- Android 12 to 14:
setInterruptionFilter(INTERRUPTION_FILTER_ALL), with Sioul's Do Not Disturb access. Android also snoozes every other mode on at that moment (Bedtime, a schedule, a driving mode) until it ends by itself. - Android 15 and later: an application that targets 15 or later may end only a mode of its own (
MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES). The switch says "This phone's own do-not-disturb stays on: turn it off in its quick settings.", with Android's do-not-disturb settings (open("modes")). - Plasma: Plasma's own,
[DoNotDisturb] Untilinplasmanotifyrc, deleted withkwriteconfig6 --file plasmanotifyrc --group DoNotDisturb --key Until --delete --notify '', KDE's own tool;--notifymakes Plasma's settings reload the group at once (KConfigWatcher). Another application's inhibition, a full-screen window or mirrored screens are not Sioul's to end: "Plasma keeps this computer's notifications back for another application or a full-screen window; it ends with them." - GNOME:
show-bannersback to true, with the person's yes ([pause] gnome); without it, "GNOME's Do Not Disturb stays on: turn it off in the top bar." - While Sioul's is off, what the system still holds is said (
dnd::still_on; this device's table:system_on,line). Nothing is ever locked: no immutable setting, never a second "off" for one change.
- Android 12 to 14:
- No mode over the system's own cause (
sioul_core::everywhere::held_by_system,Ask::stack): when the only reason for the switch's mode on a device is a press that device heard from its own system, Sioul adds no mode there: Android shows an application only the effective filter, so a mode of Sioul's would hide the end of a schedule. The device counts as silenced ("This phone is silenced by its own do-not-disturb…"); on Android, Sioul's channels that pass are still used (held.<kind>). The pause, Free time, focus and sleep enter Sioul's modes as before; when they leave, a cause that ended meanwhile shows, and becomes the "off" it is. - No loops: Sioul's own changes agree with what holds, and the settle covers the moment they take. A system "on" again within the settle after Sioul turned it off is on before and on after: neither a press nor a second "off".
- Said: while it holds, "Do not disturb on your other devices; you turned it off here." (
Here::turned_off), with Silence this device again (everywhere::again: a switch "on" heard from the system becomes the switch's own, then each mode leaves and enters afresh; on Android 16 itsSOURCE_USER_ACTIONends the person's override); while off, the "… stays on" line with what can be opened, and the last "off" heard from a system in the switch's tip ("Turned off on your phone at 14:02, outside Sioul.",last_off, twelve hours). - The phone's tile (
DndTile): "Do not disturb (Sioul)" among the quick settings, Sioul's switch pressed without opening Sioul (DndReceiver.TOGGLE,everywhere::toggle_here), lit as Rust last said (sioul_on). - Sent at once: a press made outside the window goes with the window's exchange; on a phone without the window, the background service steps at once (
StepService.HEARD, the reason "heard": no sync app asked first), or, when it does not run, Sioul's own process exchanges itself (steps::send_now).
Always through¶
config/dnd-people.toml, in the senders part, beside your lists: the people who must always reach you, each with a name, numbers and addresses, kept in the sharing itself, since the address books of two devices may not be in step. One entry per person ([[person]], keyed by its id): two devices adding two people keep both; one changed on two devices keeps the later.
- Edited in Settings ▸ What reaches you ▸ Exceptions (
qml/DndSetup.qml, its part "list"), and one person at a time from their sheet (PersonSheet.qml): Add your safe senders (each address on the Safe list, with its card's name and numbers when a card has it; each card and each number on it; everyone whose card is in a category on it; patterns such as@example.orgortel:+3319900*name nobody, said and left out), Add a contact… (from your address books), Add someone by hand, Change, Take off the list. Someone added again with one of their addresses, numbers or their card is merged into the one already there. A person without a number, or without an address, is said so under their name. - What it means is the Always through row of each channel in the matrix (attention.md), the same at every time and under do-not-disturb: as usual their calls ring and their messages come at once at any time, sleep and pauses included; their mail comes at once, told at critical urgency on a computer, but is shown without a notification while you sleep or pause. A cell may say "as their list" (=) instead. The blocked never, even on the list: blocking someone takes them off it, and putting someone blocked on it takes them off the blocked list (
porch::set_standing,porch::unblock_person). - Under do-not-disturb, everyone else is held as the Do not disturb column says: their mail shown, not told; their calls to voicemail; their messages held. Sioul's own come as their rows say: doses, codes, reminders and Health's notices; sites, other apps' automatons and the pause to move wait. Nothing is hidden from the Porch itself: do-not-disturb is about being interrupted.
- On a computer, no calls nor SMS: the list's mail comes at critical urgency, which GNOME's Do Not Disturb and Plasma's show. Plasma hides even critical ones when
[Notifications] CriticalInDndMode=false(the owner's setting), unless Sioul may "Show in do not disturb mode" ([Applications][com.aurelienpierre.Sioul] ShowPopupsInDndMode): What reaches you ▸ Do not disturb reads both, says that the list's mail cannot show then, and offers Plasma's notification settings at Sioul's page. Sioul never writes Plasma's configuration. - On a phone, calls and messages: Android has no list of its own (research: emergency-pause.md 7.1): a mode lets through calls and messages from nobody, starred contacts, contacts or anyone, a second call from the same number within 15 minutes, and the conversations marked Priority (Android 11 and later). Sioul's modes let through, as far as Android can say it, what the matrix lets through ("Its modes", above): while the phone screens calls, the Always through people's calls ring through the mode when they are among the phone's contacts (the screening declined the others before the phone rang), else when they are starred; their messages when they are starred; their conversations once marked Priority in Android, which What reaches you ▸ Exceptions opens beside a conversation set to Always through (android.md). Sioul never writes a star nor a contact (the coordinator's decision of 6 October 2026, pending the owner's: stars are your favourites everywhere, may travel with your contacts' sync, and a crash or an uninstall could leave Sioul's behind). It reads (READ_CONTACTS, asked in Settings ▸ This phone with its reason) who on the list is starred on this phone, number by number (
ContactsContract.PhoneLookup, an interface unchanged since Android 2, the same on 12 to 16), and says "Two people on your list are not starred on this phone", with each one's Open their contact (the Contacts app, where the star is) or, when no contact has their number, Add to contacts (the Contacts app's own form, filled; you save it): someone in no contact of the phone rings through no mode. Repeat callers stay let through: emergency services may call back from a number you do not know.
The phone in the background¶
"Sioul keeps your devices in step": a foreground service in a process of its own, with one quiet notification, follows your other devices while Sioul is closed: do-not-disturb within a few minutes, mail at its times. See android.md: how it wakes through Doze, what it costs, what "working" means for it (it never says the phone is in use: its exports only refresh when it last shared). A phone's sync app late or stuck does not hold the switch back where the sharing folder lives on a Nextcloud one of your accounts reaches: Sioul reads the others' files there too (database.md); with no sync app at all, Sioul keeps the folder in step itself (database.md).
- How fast a computer's switch comes: while you are awake, the phone looks every two minutes while another computer's Sioul runs, as before: the switch pressed there reaches it within two minutes. While you sleep, a computer counts only with someone at it (input within ten minutes, its session unlocked, as that computer says in its entry: database.md,
active): pressed at a computer nobody was at, the switch comes at the phone's next look, fifteen minutes away at most, and the step that brings it brings the two-minute looks with it, since a step reads the others' entries again after its own pull. A press of the switch counts as someone at that computer at once, whatever its system says of input and whatever its last reading said of its lock, and its entry goes out with the press. A computer left on at night with nobody at it no longer makes the phone look every two minutes; one whose system says nothing of it, or an older Sioul, counts while Sioul runs, as before (steps::tests::the_phone_wakes_as_often_as_someone_may_be_at_a_computer,a_press_at_a_desk_brings_the_two_minute_steps_from_the_look_that_reads_it,devices::tests::a_press_makes_this_computer_active_at_once). Until 13 October 2026, a computer counted while its Sioul ran, its tray included, and the phone looked every two minutes all night.
Older Sioul¶
- A Sioul that does not know
state/do-not-disturb.tomlnorconfig/dnd-people.tomlkeeps their records waiting for a version that knows them (the sharing'sknown_part): it writes neither, takes nothing of them out, and shares the rest. It ignores[dnd]inconfig.tomland keeps it as it is. - It writes no table of its own, nor an entry in the devices' registry: the status line says it runs an older Sioul, which cannot follow until it is updated, and never waits for it.
- Its pauses still silence it, as the pauses always did on each device.
- A Sioul before the three states ignores
mode,openandreleaseand keeps them when it writes (the table travels whole and is never written by another device). It reads Reachable as do-not-disturb off, with its usual matrix: the people do not come at once there, and a release pressed on a computer releases nothing on a phone that does not know it. The release notes say to update the phone and the computers together.
Tested¶
cargo test --release -p sioul-core everywhere: the latest press wins whatever device made it; a press after seeing another comes after it whatever the clocks; two presses that did not see each other within a minute turn it on, further apart the later; the end by each device's clock; each trigger a setting, the pause first, Free time never with it; an "off" pressed after a reason began holds it off until it ends; a forgotten focus session lets you be reached again; mail and Sioul's own notifications gated by the switch and focus only; where it holds, in words, English and French; who counts as another device; only this device's table written and a broken file left alone; the list admits its people by address and number, merges, and travels a person at a time, never read empty; the Safe list brings its people with their cards; the settings' defaults; every word in both languages.cargo test --release -p sioul-sync do_not_disturb: two devices sharing one folder, each device's table travelling whole and never written by the other, the list a person at a time (two added apart both kept, one taken off gone everywhere), and a Sioul that knows neither file writing neither and taking nothing out.dbus-run-session -- cargo test --release -p sioul-app everywhere, then… steps: what each mode asks; who on the list is not starred, in words; the background service's rhythm, and its network wakes an hour with no computer running, a computer left on with nobody at it, someone at a computer and a dose due, before and after 13 October 2026 (the longest wait between two looks, how late a computer's switch may come, among them); a press at a computer after a while away, the step that brings it bringing the two-minute looks; mail at its rhythm, never asleep nor paused, nor without accounts or the setting; nothing reaches Java on a computer; no permission to write contacts in the manifest, and no write inDndContacts.java. The do-not-disturb layer's own (… dnd::) cover the third mode beside the pauses, and the line a phone's mode says, read back from Android: today's two sentences, the matrix's parts (calls from contacts, messages from the starred, priority conversations), as Android changed them, Android 10's missing conversations, an event's alarms through or silenced.- The Java of the modes, compiled against
android-36and checked on a JVM (android/jvm-checks/ModeCheck.java): the policy made of Rust's ask (the matrix's words, nested or beside the older ones, or the olderpeoplealone), which modes let a channel that passes be used, an event's own alarm told apart from Sioul's reminder, a conversation's key as Rust's. - The record's fields a later version adds are kept and written back as they were (
settings_have_their_defaults_and_old_files_read): this device never sends another version's table or person as changed. - Both ways:
cargo test --release -p sioul-core everywhere(a change of the system presses only when it disagrees; a press heard from the system says so and holds like any; the switch held by the system alone adds no mode; a nightly schedule turns it on, then off, on every device; a press made off line meets the latest; a device turned off by hand says so, in both languages);dbus-run-session -- cargo test --release -p sioul-sync dnd(the session'sInhibitedfollowed against a stand-in server: a change that holds is told, a flicker is not, nothing before Sioul's own change settled, on again within the settle is nothing, a new server is read without telling; dconf's changes of a key told);dbus-run-session -- cargo test --release -p sioul-app dnd(held by Plasma's or GNOME's own, its end unheard said; an inhibition ended from Plasma's applet said and never asked again; Sioul's off turning the system's own off where it can and saying the rest; GNOME's switch turned off while Sioul was closed; KConfig's dates;kwriteconfig6in a folder of the test's own, telling nobody). The Java on a JVM (android/jvm-checks/HeardCheck.java:DndHeard.decide,PauseMode.kindOf,passesNowwith a held mode): the tile's off and on, a schedule's end, Sioul's own changes agreeing, the settle, on again within it, a first sight, the first change after an update or a restart heard both ways (the state found then noted,DndHeard.noted), Android 15's statuses against the mode as it is now. - The three states (part 3):
cargo test --release -p sioul-core everywhere(the quieter of three states wins within the minute, two and three devices pressing in every order, seen or unseen, past the minute the later; an older press read by itson, a word unknown too, Reachable writtenon = false; Reachable holds the night, focus and Free time off while it lasts, they hold again after it, no pause held off, none during a pause, a pause pressed after it ends it; its lengths by day and at night; release stamps after every press known, devices gone passed over, this one never),… attention(Reachable at every time and under each layer: everyone not blocked through, mail of every address told, the screening's rows and the blocked as they are),… calls(the frames'reachablecolumn, cut at its edges; R1),… appnotes(the listener under Reachable at five hours and both gates: the people at once, the blocked never, automatons at their gathered times; the release ledger: each stamp once, what was held before it only, every kind but what is held for good, an automaton held after it at its gathered time, a stamp ahead of the phone's clock read as its now, kept across a restart:Decision::released);dbus-run-session -- cargo test --release -p sioul-app everywhere(the moment's three states, Reachable's words and "until you turn it off", none during a pause); the QML testtests/qml/tst_dnd.qml(Reachable's lengths, said, never offered during a pause; a computer's "Let what your phone holds through");android/jvm-checks(DecideCheck: R1 indecideFor). - After the review of part 3 (20 October 2026):
cargo test --release -p sioul-core everywhere(a gone device read as As usual, its Reachable and Do not disturb too, holding nothing off, releasing nothing, following nothing:a_gone_device_s_press_still_ends_what_came_before_it; Reachable's latest end for every length, a press with no end, one a year ahead, no overflow:reachable_never_outlives_its_latest_end; what As usual held off stays held off after Reachable, by the same device or another, and the plain case:reachable_s_end_keeps_what_as_usual_held_off; a stamp ten minutes ahead, another device's apart, one at the end of time said once and never followed by the clock:release_stamps_never_block_one_another; three devices,a_press_overridden_knowingly_never_comes_back; a pause from a clock behind,a_pause_that_knew_of_reachable_ends_it_whatever_its_clock),… appnotes(under_reachable_a_conversation_gathered_comes_at_once; the ledger by device, an older ledger's single stamp read as a floor);dbus-run-session -- cargo test --release -p sioul-app(the files read by the window and bydnd_from_filesalike, a gone device, a pause ending Reachable:every_reading_reads_a_gone_device_and_a_pause_alike;reachable_is_read_anew_when_the_switch_changes;the_table_s_layers_read_the_switch_anew;the_moment_says_a_pause_whatever_do_not_disturb_says_of_pauses; no release during a pause, then once after it, a notification held again meanwhile too:no_release_during_a_pause_it_waits_for_its_end); the QML testtst_dnd.qml(a length that meets the night said with its latest end; no release offered during a pause). - After its re-check (20 October 2026):
cargo test --release -p sioul-core everywhere(a_gone_device_s_expecting_a_call_opens_nothing,a_release_far_ahead_never_drags_the_presses,a_press_far_ahead_never_wins_for_ever,a_gone_device_s_as_usual_gives_reachable_nothing_to_carry),… appnotes(a_release_passed_over_as_ahead_is_passed_over_for_good);dbus-run-session -- cargo test --release -p sioul-app(a_gone_device_never_opens_the_screening, end to end as on a phone,SIOUL_CALLSin a process of its own;reachable_pressed_after_a_gone_device_s_as_usual_carries_nothing).
Not built¶
- Sioul starring the list's people itself (WRITE_CONTACTS, with your yes, its own stars only, taken back when someone leaves the list): held until the owner decides; it would build on the guided version.
- A device's words in the others' language: each device writes its system's answer in its own language.
- Measured on a phone: estimated so far (android.md).
- A command for macOS's Shortcuts automations (macOS 26: "When Do Not Disturb is turned off" running
sioul dnd …): possible, not built; nothing else lets Sioul hear a Mac's Focus. - Both ways tried on Plasma itself: built and checked on a computer (Rust's tests, the Java on a JVM:
android/jvm-checks/), not yet on Plasma itself. Tried on a phone, below.
Tried on a phone¶
8 October 2026, a phone on Android 12 (/e/OS), Sioul with Do Not Disturb access and notification access; the phone's own do-not-disturb turned on, then off, with adb shell cmd notification set_dnd on and off, and put back as it was; the times from adb logcat -s sioul and the notification read every quarter of a second (dumpsys notification):
- 0.0.3: the first change after the update was not heard ("first sight", above); the next ones were, within a second (Android 12 sends
ACTION_INTERRUPTION_FILTER_CHANGEDto the manifest receiver of a package with Do Not Disturb access). The background service's notification kept "Every call rings until 09:32." at 09:39: its words came only with a step, and no step runs while the window is on the screen. - With the fix, Sioul's window closed (just updated): the first change after the update heard at once ("the filter heard: on", the switch pressed and sent); the listener's word of it found nothing new; off heard at once, Sioul's mode left. The notification said each change within a tenth of a second (76 milliseconds after "on" was heard: "Do not disturb here; your other devices' news is on its way."; 45 after "off": "Do not disturb is off."), after a first try showed "off" only 3.4 seconds late: its words waited in Android's queue of background broadcasts behind
DndReceiver's own, held open while Sioul's change settled; they go on the foreground queue now, told once this device's table is written. - Sioul's off turns the phone's off: the phone's own on (heard, Sioul's switch on), then Sioul's switch pressed off in its status line: the phone's own off 45 milliseconds later (Android 12,
setInterruptionFilter(ALL)), the notification 90 milliseconds after. - Not checked: a computer following the phone's press (the press was sent: "sharing: 1 sent"); Android 15 and later, where Sioul says the phone's own stays on.