Tasks, notes, links and focus¶
A plan written in prose is a wall: every line is there at once, and the next step has to be found again each time. Sioul turns the plan into tasks that wait for each other, shows the one step to take now with the reason, and keeps every task tied to what it needs: its notes, the mail it came from, the people, the drafts, the project. The research behind each choice is in research.md, findings 6 to 20.
Calm first, for tasks¶
- One next step, picked for you, with its reason. "Now" shows one step, why it comes now ("its date is 30 October: three weeks left"; "it frees two other steps"), and the one after it. Equal steps are not shown as a choice to make: Sioul picks, and says it picked. Two other choices wait behind one click.
- Nothing is ever overdue. A day to start that passed says nothing: the task is simply free. The date asked from outside (DUE) is said as time left; once passed, as "Date asked: 1 October", never in red, never counted. The plan always starts from today.
- "Not now" is honoured without argument. It puts the step's whole stream off until tomorrow (the tasks tied to it by what they wait for or by being steps of the same task), so what comes next is free to start, not its own next step; streams are ranked by how soon their dates come. A new day starts clean.
- Optional stays optional. A task tagged
joy(only if you want to) is offered in a fold, never proposed as the next step; one taggedsomeday(when you say so) is parked at the end of the list. Neither takes room in the plan. - Starting is the hard part, so it is helped. "Start" offers two minutes first; "What makes it hard?" gives one matching help per answer: its details opened (its notes and messages), a step added, two minutes offered under the card ("Just two minutes", which starts the time only when pressed), a lighter day. Only "Start" starts the time: an answer records or offers, never starts.
- Time made visible, without pressure. The focus window stays on top while you work elsewhere: a disc drains in a neutral colour, with no ticking and no sound. Two minutes before the end it says it is time to find a stopping point; at the end, "Keep going" or "Stop here, it counts". Stopping offers one line, "next time, start by…", shown when the task comes back.
- How much a day holds is yours to say. "How is today?": clear, haze or fog. Haze keeps less for today; fog shows only small steps, and one step is a full day. Nothing is inferred from what you do.
- Finishing says what it changed. "Done. This frees: Send the registered letter." Once, in the status line.
- Nothing counts what you did not do. No streaks, no postponement counters, no score. "Done this week" shows what got done.
- The plan proposes; your dates stay yours. The days the plan gives each task are computed each time, from today, and never written into the tasks. Only what you set (a day to start, a date asked, an order) is stored, and the times you pin tasks to, kept as events in a calendar ("Pinned to a time", below). The plan is made again when Sioul starts, every twelve hours, at midnight, and at once whenever something it depends on changes: a task made, changed, done, dropped, deleted or put off ("Not now"), an estimate, time noted, an event made, moved, deleted, accepted or declined, a meal, a nap or the night changed for a day or as usual, your hours and days off, the day's weather, "Done for today" and work now, what your other devices or a sync bring, the capacity settings. Each change asks for it, off the window's thread, several in a row making it once (
backend::coalesced); the day is laid again with it. A task not done by its planned day moves on, and what waits for it follows. - "Done for today" closes the day, early or not. It opens the end of the work day first (reviews.md): what was said of the morning, how the day felt, its mix, a note, each optional; Close the work day closes it with no answer as well as with, and nothing asks whether to stop. "Undo" waits in the status line. At the end of the day's last hours the status line offers it, with one quiet notice, once; before sleep, Close the whole day looks back over the whole day. Today's room goes to zero and the plan flows on into the next days with room, never above a day's room; nothing is written into the tasks. A screen, read in ten seconds, says when work comes back, what got done or worked on (only if something was), that everything else has its place, the first step when work comes back (the line left when a session stopped, else the plan's first step, one tap to say it your way), a date asked before then if there is one (with "Ask for more time", or leave it), and what still gets through. No count of what was not done, no history of early stops, no "are you sure". The next working day opens on that step, never on yesterday. Then quiet time until work comes back (porch.md): "Rest of the day", only what is yours; a thought noted then waits, out of sight, for work to come back. Findings 21 to 23 of research.md.
- Offices have hours. A task marked "Needs an open office" is proposed only while offices are open (Tasks ⚙, Monday to Friday 9:00–17:00 by default) and planned only on those days; on a Saturday, the next step is one you can do.
In the standards¶
Tasks are CalDAV tasks (VTODO, RFC 5545 §3.6.2) in task lists on your calendar server, so any client and any device sees them. What ties them together is written into them, in RFC 9253's terms where it exists:
| What | Written as |
|---|---|
| A task | a VTODO in a task list (a calendar whose supported-calendar-component-set holds VTODO) |
| A step of a bigger task | RELATED-TO;RELTYPE=PARENT:<UID>, in the step |
| Waits for another task | RELATED-TO;RELTYPE=DEPENDS-ON:<UID>, in the one that waits. With a gap ("the answer comes within two weeks"): RELATED-TO;RELTYPE=FINISHTOSTART;GAP=P14D:<UID> in the one that comes first, as RFC 9253 §4 places temporal links. Both are read; NEXT too. |
| Can start from | DTSTART (a date, or a time in UTC) |
| The date asked | DUE |
| How long it takes | ESTIMATED-DURATION:PT15M (draft-ietf-calext-ical-tasks) |
| Who does it, what it is about | CATEGORIES: you, proxy (someone with you or for you), joy, someday, and topics |
| Its kind: a call, writing, online (a form), going out, reading, thinking, making, or one of yours (Tasks ⚙: renamed, taken away, added) | CONCEPT:tag:aurelienpierre.com,2026:sioul/task-type/call (RFC 9253 §7.3, a tag URI, RFC 4151); other applications' concepts are left as they are |
| Needs an open office | CONCEPT:tag:aurelienpierre.com,2026:sioul/needs/office-hours |
| Its project | REFID:<project id> (notes-folder.md) |
| Its notes, the mail it came from, its drafts, an event | LINK;LINKREL=describedby (a note), via (what it was made from), related; VALUE=URI for a note, a message or a draft, VALUE=UID for an event |
| The people and offices involved | CONTACT;ALTREP="sioul:contact/<UID>":<name> |
| Order among equals | PRIORITY (1 first) |
| Time kept before and after it, in minutes: getting there, getting ready, coming back (events too) | X-SIOUL-BEFORE:20, X-SIOUL-AFTER:15 |
| What it costs and what it gives back, 0 to 10 each as you rate them, the rated ones only (events too): thinking, feelings, anxiety, body and senses | X-SIOUL-COST:COGNITIVE=3;EMOTIONAL=5;ANXIETY=7;BODY=2, X-SIOUL-GAIN:6 |
| How it was, said after it, optional: one rating a day, the newest five kept (capacity.md) | X-SIOUL-FELT-COST;X-SIOUL-ON=20261006:ANXIETY=3, X-SIOUL-FELT-GAIN;X-SIOUL-ON=20261006:6 |
| Its first estimate, written by Sioul when it first has one, never changed | X-SIOUL-ESTIMATE-FIRST:PT30M |
| Pinned to a time ("Do at…", a step dragged in the day view) | a time block: an event in a calendar ("Pinned to a time", below); the task links to its current block only: LINK;LINKREL="tag:aurelienpierre.com,2026:sioul/rel/time-block";VALUE=UID:<the event's UID> |
| A time given to a step for one day by a drag, before time blocks | X-SIOUL-AT:20261006T123000Z (UTC): read for compatibility, never written now; one for today or later becomes a block once, the line taken out. Not DTSTART: RFC 5545 §3.8.2.3 wants DUE of DTSTART's value type and later than it, and servers that check (Sabre: Nextcloud) refuse a task whose start has a time while its date asked is a date, or has passed; nor a line of the task's own: other applications never show it |
| Light, heavy or what gives back: chosen, or computed from its costs once one is rated (none for the usual) | X-SIOUL-ENERGY:HEAVY |
| Comes back | RRULE:FREQ=…; done, it moves to its next turn after today, as tasks.org does |
| Done | STATUS:COMPLETED, COMPLETED, PERCENT-COMPLETE:100 |
- Editing keeps the rest: tasks are changed line by line, as contacts and events are; what Sioul does not edit (alarms, another application's fields) comes back exactly; a form saved unchanged writes nothing.
- New lists are created on the server with MKCALENDAR (RFC 4791 §5.3.1), new address books with an extended MKCOL (RFC 5689), at the next sync; until then they wait here, and a sync never deletes them. A list in the account
localstays on this device. - Things are named by addresses:
mid:<Message-ID>for a message (RFC 2392);sioul:task/<UID>,sioul:event/<UID>,sioul:contact/<UID>,sioul:note/<path>,sioul:draft/<id>,sioul:project/<id>(sioul:case/<id>as written before),sioul:budget/<budget>/<line>. - Each link lives in the thing that makes it: a task or an event (above), a note (a Markdown link, or its front matter:
task:,event:,mail:,links:), a draft (itslinks), a budget line (itslinks). What none of them can hold (a message is never changed) goes in$XDG_DATA_HOME/sioul/links.toml. Links are read both ways: every thing shows what it points at and what points at it. - Time spent is kept in plain files, one per month (
$XDG_DATA_HOME/sioul/time/2026-10.toml), not in CalDAV: it is your record, not the task's. Each record says how its minutes were known (kind): measured by the timer, typed by hand, or measured then corrected by hand; one written before that was kept reads as unknown. The session running now is kept too, so closing the window loses nothing.
The plan¶
- Order: Kahn's algorithm over the open tasks; a step waits for what its bigger task waits for, and a bigger task ends with its last step. Tasks that wait for each other in a loop are found (Tarjan's strongly connected components) and said: "These wait for each other: A, B. One of them has to go first."
- The next step, among the tasks free to start: the one started; then the one whose latest start comes first (its date, or a later task's, minus the work in between); then your PRIORITY; then the one that frees the most others; then the smaller.
- Days: each open task goes into the first days with room, in that order, never before today, never before what it waits for (plus its gap). Room is your hours (areas.md), each kind for its own tasks: work hours for work, admin hours for your admin; admin without hours of its own goes to work hours, work without hours to admin hours; leisure has no hours, so what is only for leisure takes no room and waits for none. Within that room, what a day holds: each day is filled to 85 % of what it holds for you on each cost and in total, learned from your own days (capacity.md; "as now" until your days say more, so that nothing changes at first). The events in them are taken out, with a pause of five minutes before and after each, and each step leaves a pause of five minutes after it; not an event cancelled, one marked free (
TRANSP:TRANSPARENT: a holiday, "working from home"), nor an invitation you declined (your ownPARTSTAT=DECLINED, by your accounts' addresses), which hold no time and still show in the agenda (Occurrence::holds_time,plan::event_spans; the same for the day's layout, meals moved past events, and what a day's events cost,capacity::held_by_events). A step up to an hour is never cut; a longer one is cut in parts of a quarter of an hour at least. Margins are not pauses: a task's room is its length plus the time kept before and after it. A task with margins is never cut (going there twice is not the same step): the plan lays it whole on the first day whose room holds it, or on a day of its own when no day's room does (plan.rs,whole,alone); the day lays it in one piece, its margins at both ends, in the first gap that holds it, or says it does not fit (dayview.rs). An event's margins are taken out before its pauses. No hours set at all: Monday to Friday, 9:00 to 17:00, for everything. Today's room, and what today holds, start now and are scaled by the weather (haze 60 %, fog 30 %). Each task is laid at its corrected length, your estimate times how long tasks like it take you, and each day keeps free time for steps running long and half an hour for a slot of time for you (capacity.md). Days off and today once closed have no room; a task that needs an office goes only on days offices open. A task whose plan ends after its date says so once, calmly, with what would help: doing it sooner, making it smaller, handing it over. - Streams: tasks tied by what they wait for or by being steps of the same task form a stream (union-find); "Not now" sets a whole stream aside for the day, and the next step comes from another stream.
- Waiting on others: a task done starts the clock of what waits for it with a gap; the next one waits until then, and says until when.
- Consistent constraints: the next step is never a task that waits for one still open, nor one whose day is ahead, even when it was started too soon (it stays in "Started", and says what it waits for); never a call to an office that is closed now.
- An office's own hours: a task that needs an open office takes, when you say them, its office's opening hours, in its panel: open from a day to a day, from a time to a time, and a second range for a lunch break ("mo-fr 09:00-12:00, 14:00-17:00",
X-SIOUL-OFFICE-HOURS). It is then proposed only while that office is open, planned on its days, and the note says when it opens next; without them, offices' usual hours ([[office_hours]], Monday to Friday 9:00–17:00). - What it is for: work, your admin, leisure, any of them together (
X-SIOUL-AREA), else as its tags say; the task pages show what fits the hours now (areas.md).
Pinned to a time¶
A task is pinned to a time by a time block: an event in a calendar, tied to the task both ways (sioul_core::blocks; the window's side, crates/sioul-app/src/blocks.rs).
- Why an event. An event shows in every calendar application, a phone's too, moves there like any other, and is a standard object. The alternatives were worse: a line of the task's own (
X-SIOUL-AT, written for drags until blocks) is invisible to other applications; a time on the task'sDTSTARTbreaks when itsDUEis a date (RFC 5545 §3.8.2.3 wants the same value type, and Sabre, Nextcloud's server, refuses the task with a 415), and would change what "can start from" means. - The block:
SUMMARY, the task's title, kept in step (the task renamed in Sioul, at once; elsewhere, at the next re-plan; the block renamed in Sioul's event form renames the task);DTSTARTandDTENDin UTC; busy,TRANSP:OPAQUE;X-SIOUL-TASK:<the task's UID>, which Sioul reads, andLINK;LINKREL="tag:aurelienpierre.com,2026:sioul/rel/block-of";VALUE=UID:<the task's UID>(RFC 9253 §8.2; LINKREL takes a registered relation or a URI: a tag URI, RFC 4151, as the task kinds); for a repeating task, the turn it pins,X-SIOUL-TURN:2026-10-09(its date asked, else its day to start, when pinned). NoVALARMunless Tasks ⚙ asks for one ("An alarm in each block"): Sioul reminds of a block as of any event (reminders.md), and a phone with its own calendar would remind twice; asked, it comes five minutes before (TRIGGER:-PT5M), in the blocks made or moved from then on. - Its length: what the plan lays for the task (its corrected estimate, less the time spent), its margins aside, by whole five minutes, a quarter of an hour at least; "Do at…" changes it; a step dragged in the day keeps its card's length. The task's margins are kept around the block, never inside it.
- Its calendar (Tasks ⚙, "Time blocks go into"): unsaid, « Planned tasks » (« Tâches planifiées »), made at first use on the account of the task's list (
MKCALENDARat the next sync), its folder and its addressplanned-taskson every device, so that two devices make one calendar; for a list kept on this device, or on an account Sioul makes no calendar on (Google), it is kept on this device. Or any calendar that can be written and holds events; a Google calendar adds its default reminders to every event it receives, a block too (google.md), and blocks there are not tried against Google yet. - Pinning: "Do at…" in a task's details (a day, a time, a length), a step dragged in the Tasks day view, or the block itself dragged in the agenda or in any calendar application. The task's block is moved, or made; the task linked to it and to it alone (
blocks::task_pinned); "Undo" puts both files back unless something changed them since. - Seen, quietly (the accent colour, never a warning's): in the task's details, near its title, a pin and its block's day and time in words ("Pinned: today, 14:00–14:45"; "Pinned: Thursday 8 October, 10:00–10:30"); a click opens the block in the agenda, its menu (right click, a long press, or ⋯) offers "Move…" ("Do at…" again) and "Let the plan place it". A row of the list and a card of the board show a small pin and its time ("14:00", another day "Thu 8 Oct 10:00"); Now's card the pin and when, when the next step is pinned; the day a pin on its card. A block over, the task not done, shows no pin: the task is back in the plan (Breeze's
pinicon, bundled,tools/bundle-icons.py). - What the plan does (
plan.rs,dayview.rs): a task is pinned to its first block still to come, open, of its turn (blocks::Blocks::of); its other blocks wait their turn and hold nothing. A block of a task known here is never an event to the plan, the day or the record (blocks::without_blocks): its time, its margins and a pause around it leave its day's room once (Settings::with_pins); the task is laid on that day before the others, its block's minutes counted as its own (its load, a heavy step, the free time kept), whatever the room, the budgets or what it waits for; the free time around it filled as usual, everything after it re-planned at once. Longer than its block, the rest goes on from the next day. The day lays it in its block, its margins around it, its time in the accent colour. Now puts a step pinned more than a quarter of an hour ahead after the others. Meals move past a block as past any event (as the Health page moves them). Blocks are read in the plan's four weeks of events, and in the calendars made or chosen for them as far as the plan goes. - Elsewhere: a block moved in another application moves the task at the next sync; deleted there, the task is no longer pinned. The task's link to it goes the next time Sioul pins it or leaves it to the plan: nothing is written in a task in the background, where another device's sync could race it into a conflict.
- Over, the task not done: it pins nothing; the task returns to the plan; the block stays as it was, with no "missed" and no count.
- Done or dropped (here, or found so at a re-plan): a block not begun is deleted, its time freed; one under way ends then (when it was done; dropped, now); one over stays, the record of when the work was done, and the day shows the task done there. Deleted: its blocks to come go with it, under one "Undo" (
mail::schedule_removals). - "Let the plan place it": its blocks not begun deleted after ten seconds, one under way ending now, the task's link taken out at once; "Undo" puts everything back.
- A repeating task: a block pins one turn. A turn done here closes its blocks as above; one done elsewhere moves the task's dates on, so its block pins nothing, and goes when it is still to come. Its dates changed in Sioul's form: the block follows the new turn.
- Set right at each re-plan (
blocks::upkeep), only what differs, so that nothing is written twice. A block whose task is not known here (not synced yet, deleted elsewhere) is an event like any other, and left alone. X-SIOUL-AT: read for compatibility (the plan and the day lay such a step today, as before), never written. One for today or later, on an open task, becomes a block once, and the line goes from the task.
Places¶
- Where you stopped: one line, left whenever something interrupts you (a pause to move taken, a meal's or the night's notice and its Options…, the pause to move's notice and its Where I stopped…, the end of the day, a timer stopped, or New ▸ Where I stopped… at any time), shown again at the top of the Porch and of this page, and in the focus window, until "Done" (
sioul_core::stopped,StoppedCard.qml; carried to your other devices). Stopping then costs no fear of forgetting where you were: a cue to resume cuts the time to get back into a task (Trafton et al. 2003; Leroy & Glomb 2018). A timer stopped without a word keeps the line left at its pause. - The time running, in the system's notifications: while a session runs, one notification says its task and since when ("Since 14:02, 25 min chosen"; paused, "Paused, 12 min so far"), with Pause (Go on) and Stop, the focus window's own buttons; a click on it opens the task. It follows the session from wherever it changes (the window, the notification, another device,
sioul focus), after each reading of the tasks and at the window's minute (timenote.rs). On a Linux desktop, the desktop's (sioul_sync::notify::ongoing, on a D-Bus connection of its own, which hears its buttons): resident, without sound, at normal urgency, for Plasma shows a low one nowhere by default; where the server keeps what it shows (Plasma's history, GNOME's tray), it goes there after its popup, buttons alive, elsewhere it never expires; taken away when Sioul quits. A session bus that does not give its connection (a stall), or loses it, does not lose it for the session: its connection is made again, five seconds apart, what changed meanwhile shown then (review of battery part C, L4). A notification server that answers late never gets it twice: while its Notify is not answered, none other is sent, its late answer gives its number, and what changed meanwhile goes in its place; closed by that number (the fourth review's L1;notify::tests::a_lasting_notice_answered_late_is_never_shown_twice); taken away before that answer comes, it is closed once it comes, half a minute at most (CLOSE_LATE; the fifth review's L4;notify::tests::reminders_keep_their_word). On Windows and macOS, none yet:notify::ongoingdoes nothing there, and the focus window alone shows the time. On a phone, Android's, with a chronometer, its buttons working without the window (android.md, "The time running"). - Now: the next step and why, its estimate and where you stopped, "Start", "Done", "Not now", "What makes it hard?"; after that, the next one in a line; folded: two other choices, what is started, what you might do if you want, what got done this week.
- List: every open task, a bigger task followed by its steps, in the plan's order, grouped by project or by list; a search; done tasks on request; the optional ones last.
- Board: free to start, started, waiting, done (two weeks). Cards move by dragging, with a mouse or a touchpad (
acceptedDevices): to "Started", to "Done", back to "Free"; on a touch screen a drag scrolls the board. "Waiting" is decided by what each task waits for, and each card says what. More than three started: one line asks whether to finish or park one. - Calendar (a Gantt chart;
task-mode-timeline, "timeline" in the code andsioul tasks timeline), on demand: each open task on its days, the date asked as a small diamond, days without room shaded, one project or all. - A task, open on the right, its details first, from any view: a click (list, board, calendar, the day), "Details" in its menu (right click, or a long press on a touch screen: lists and the calendar), "Details" on Now's card. Nothing starts: start, done, not now; what matters in words; its tags, steps (ticked there), what it waits for and frees; its fields in words, only those said (
TaskPanel.facts); its notes as written; everything tied to it, and "Write an email" (a draft to the people it involves, linked both ways) or "Make a note". "Edit" at the top turns the details into its form, "Details" back: its steps and one more in a line, what it waits for (removable, one more found by its title, with "Then wait": a gap in days or weeks for the next one added, written assioul tasks importwrites it,tasks::set_gap; each wait shows its gap,taskview::gap_words), and under "More" every field (dates, length, margins, the costs' tiles, what it takes, project, billed, kind, area, office hours, how it comes back, list, notes in Markdown), each saved as it changes; a change made right after another goes on from it (change()keeps what it saved until the task is read again). Done, its details offer "How was it?" (below). - A new task opens in full: New ▸ A task, "New task" beside the line at the top of the page, and Add ▾ ▸ A task on any card open the panel on a new task's form (
newTaskForm,TaskPanel.startNew), every field unfolded, the title focused. From a card it starts with what that card gives, as a task made from it always did: a message's subject, the message linked (via), its sender and its project; for an event, "Prepare: …", its day as the date asked, the event linked, its projects; anything else, its title and a tie (a contact involved, a project, a note describing it, anything related). The fields are kept in the form until the title is given, by Enter or by leaving the field in any way (another field, Close, Escape, Back); the task is then made with all of them (save_taskwith no UID), in the list the form shows: the usual one (Tasks ⚙, "New tasks go into"), else the first made for tasks, unless another is chosen there. The panel then goes on as the task's form. Closed without a title, nothing is made; a task made by mistake is deleted like any other, "Undo" offered. Until the task is read back (the plan is computed again on a thread, a moment), the form keeps what is changed and saves it then. Asleep, the page shows anyway, as "Show anyway" does. Why the title makes it: a task file needs a title, and making it at once keeps every later field saved as it changes, as for any task; nothing waits in a draft that a closed window could lose. - How was it? A task done, whichever way (a list, its panel, the focus window: the backend's
task_donesignal), the status line offers "How was it?" while it says the task is done; a done task's details offer it too (HowWasIt.qml,FeltRatings.qml). The same tiles, what was foreseen shown as a thin mark on each gauge and nothing faint proposed; only what is tapped is kept as felt (set_felt: today's rating written alone, from the file as it is), never copied from the forecast, whose bias it would bring back (research criteria 6 and 7). Ignored, nothing changes; never asked twice, never counted. - One line makes a task, from any place on the page: "Call the tax office tomorrow ~15m #taxes {30/10}". At the end of the line, in French or English: the day to start ("tomorrow", "vendredi", "next week", "dans 3 jours", "30/10", "30 octobre"),
~how long,#a project or a tag,{…}the date asked; "@day" anywhere, and "@call", "@write", "@online", "@out", "@read", "@think", "@make" (or "@appel", "@écrire", "@enligne", "@dehors", "@lire", "@réfléchir", "@faire") for its kind. Without one, a first word that says it plainly gives the kind ("Call…", "Remplir…"); "Ask…" says nothing, as it could be a call or a message. What was understood shows as chips before Enter. Enter makes it, in the usual list, and opens it; in quiet time it is noted for when work comes back instead (its day to start set then), out of sight. - One kind, one category: two choices at the top of the page show only those tasks in every view, Now included ("the next call"); the plan stays whole, so a call that waits for a message still waits. The choices (and the list's grouping, done tasks, one project) are kept between sessions (
$XDG_STATE_HOME/sioul/tasks-view.toml); searches are not. - Kinds and categories are yours (Tasks ⚙): a kind is renamed in place, taken away (tasks keep it) or added (
[[tasks.kind]], its id written in the task's concept, "@" and its name in one line); a category is renamed on every task that has it (a name already used merges them) or, after a second word, taken off them all. - Notes: the notes folder, read as Obsidian reads a vault:
[[wikilinks]](found by name anywhere, the same folder first, then the shortest path, then aliases), Markdown links,#tags, front matter, links back. Nextcloud Notes' folder works as well: its categories are folders, and its.txtnotes (its default) are read and written as Markdown like.mdones, keeping their extension (notes::kind_of_file,notes::text_stem); new notes are.md. Search first, the notes changed lately on top, then every note as one list (each with its folder) or as a tree of folders, folded until opened (the choice is kept). A note opens read, its links followed with a click wherever they lead; editing is one switch away. Unticked- [ ]lines are one click from becoming tasks, linked to their note. - Pictures, PDFs and sounds are notes too: listed beside the Markdown files (
png,jpg,gif,webp,svg;pdf;ogg,opus,mp3,m4a,wav,flac…), opened in place (a picture fitted to the page, a PDF's pages with QtPdf, a sound with play, pause and where it is), and tied like any note (sioul:note/<path>).![[scan.png]]shows the picture inside a note, at most as wide as the page; any other embed is a link. "Record an audio memo" records into<notes>/memos/as Opus, the microphone open only while it records, and opens it as a note. - Renaming and deleting notes (right click): a new name takes the notes that name it along (
[[name]],![[name.png]], Markdown links by path,sioul:note/addresses), and the tasks and ties that link to it; deleting moves it into the vault's.trash, as Obsidian does, "Undo" offered. - Lists, calendars and address books (Tasks ⚙, Agenda ⚙, Contacts ⚙): renamed in place, here and then on the server (
PROPPATCH); an empty one deleted, here and then on the server, unless something was put in it there meanwhile (DELETE); one holding anything stays. - Everything made from everything, linked both ways: a task, an event or a note from a message; a note for an event (dated, its guests listed), then sent to the guests; a task to prepare an event; a task from a note's line; an email from a task. Every message, event, contact, task and note shows what it is tied to.
- Links by hand: every card ends with "Add ▾" (a task, an event, a note, a message, or a sender into the contacts) and "Link to…", which finds anything by a few words of its title, of one kind or all (
World::search). Right click on a task, an event, a note, a contact, a message, a Porch line or a budget line offers the same; right click on a tie undoes it. A tie is written where it can be held (Loaded::tie): in the task when one end is a task (so the server and your other devices carry it), else in an event whose calendar can be written, else in a note's front matter (links:), else inlinks.toml. Undoing takes it out wherever it is written; a step, a wait, a guest or a link in a note's text is changed where it is, and that is said.
Command line¶
sioul tasks [now] the next step, why, and the one after it
sioul tasks list [--by project|list] [--done] [words]
sioul tasks board | timeline [--project <id>] | show <task>
sioul tasks add "Call the tax office tomorrow ~15m #taxes" [--list <account/id>] [--parent <task>] [--after <task>]
sioul tasks done | start | not-now <task> (a task: its UID, or the start of its title)
sioul tasks weather clear|haze|fog
sioul tasks lists | new-list <account|local> <name> [--events]
sioul tasks import <file.toml> [--dry-run] [--no-sync]
sioul dav new-book <account> <name>
sioul focus start <task> [--minutes 25] | status | stop [--done] [--note "…"]
sioul links <address> what a thing is tied to, both ways
sioul notes [words] | notes --path <path in the store>
Importing¶
sioul tasks import reads a TOML file of tasks, offices and drafts, for agents and scripts. Each entry has a key; UIDs are the file's prefix and the key, so importing again changes what the file made, line by line, instead of adding it twice. What you added since (a link, a tag, a tick) stays.
list = "account/plan" # where new tasks go (else the first list made for tasks)
book = "account/admin" # where new contacts go
prefix = "plan-"
[[contact]]
key = "office"
name = "Tax office"
phones = ["+33 3 00 00 00 00"]
address = "1 rue de l'Exemple, 75001 Paris"
[[draft]] # kept in Sioul; nothing is sent
key = "ask"
account = "mail-account-id"
to = ["office@example.org"]
subject = "Late returns"
body = "…"
[[task]]
key = "send"
title = "Send the registered letter"
parent = "returns" # a key, or "uid:<UID>"
after = ["gather"] # waits for
after_gap = { letter = 14 } # waits 14 days after "letter" is done
start = "2026-10-15" # can start from
due = "2026-10-30" # the date asked
estimate = 20
priority = 3
tags = ["you", "admin"]
projects = ["taxes"] # its projects' ids ("cases", as files written before say, reads too)
note = ["admin/letters.md"] # notes of the notes folder
links = [{ uri = "mid:abc@example.org", rel = "via" }]
contacts = ["office"]
drafts = ["ask"]
done = "2026-10-01" # already done, on that day
[[event]] # an appointment: an event, never a task
key = "dentist"
title = "Dentist"
start = "2026-10-23T14:00" # a time, or a day for a whole day
end = "2026-10-23T14:45" # unsaid: an hour after a time
location = "1 rue de l'Exemple, 75001 Paris"
calendar = "account/personal" # else the file's `calendar`, else Settings ▸ Agenda's
A task or an appointment is the file's to say, never guessed from its times (21 October 2026): a task can start at a time and still be a task. An appointment is an [[event]]. A [[task]] with what only an appointment has (end, all_day, calendar, attendees, organizer, or kind = "appointment") stops the import and asks which it is; any other field a task does not read is said, and left out. A key moved from [[task]] to [[event]] makes the event, with the same UID, and takes the task out with its time blocks, in one step of the move journal (vdir::replace_items: never both, never neither). A key in both stops the import. The MCP's add_task and add_event say the same to agents: ask the person when they did not say which.
A task or an appointment, in the agenda¶
A task shows in the agenda only through its time block ("Pinned to a time"). It shows as the task it is (21 October 2026): the task mark (Breeze's view-task) where an event has its calendar's colour, "Task · pim::agenda_read, agenda::mark_tasks; homecard::tests::every_agenda_reads_the_same_items), and only the calendars that take events (database.md, "What a calendar takes"): a task list's own tasks are the task views'. A block kept in a calendar of this device's own for a task whose list is a server's goes to that list's account, to the calendar for blocks there, at the next re-plan (blocks::kept_back): until 21 October 2026 such a block showed the task's time on one device only.
- "Make it an appointment", on a task's block (its details or its menu): the event form opens with the task's title, place, notes, repeat, margins and costs, at the block's time (else the task's own time for its estimate, or an hour; else 9:00 on its day, to set), in the calendar Settings ▸ Agenda names for new events, or another chosen there. Saved, the event is written and the task taken out with its blocks to come and the block it was opened from (
appointments). A task with steps of its own stays a task. - "Make it a task", on an event of your own: a task in the usual list, its day its day to start, its length its estimate; its time, still to come and not repeating, becomes its block. An invitation stays an event (others expect you there), and so does a repeat a task cannot say (every other Tuesday).
From the research, built and next¶
| Idea | Where it stands |
|---|---|
| One next step, picked, with its reason; ties picked and said | built |
| No overdue: plan date and date asked apart | built |
| Two-minute start, stopping counts | built |
| "What makes it hard?", one help each | built, without the AI |
| A breadcrumb when stopping | built: one line on stopping, shown when the task comes back |
| The day's weather sets its room; fog shows small steps | built |
What a task takes (energy accounting, Toudal & Attwood; Structured's Energy Monitor without points): light, the usual, heavy, or "it gives back" (a walk, music), in the panel's "More" (X-SIOUL-ENERGY). A day takes two heavy tasks when clear, one in haze, none in fog: the next goes to a day that can take it; in fog a heavy task is the next step only when nothing lighter is free, and says so. What gives back takes no room and is never proposed: after a heavy step done within two hours, it is offered on Now. No gauge, no score, no red (plan.rs, taskview::now) |
built |
| Time made visible: a draining disc, a heads-up before the end, no sound | built |
What a task or an event asks, and what it gives back: minutes kept before and after it (getting there, getting ready, coming back), kept free in the plan and shown apart in the day ("Around: …"), never counted as a pause; costs from 0 to 10 (cognitive, emotional, anxiety, body and senses; COPSOQ and the demand–control tradition keep cognitive and emotional demands apart, aversiveness predicts putting off, physical and sensory load brings on crashes in energy-limiting illness and autistic burnout) and a gain from 0 to 10, each a tile in the task's form and the event's (CostTiles.qml; capacity.md): Thinking, Feelings, Worry, Body and senses two by two, Gives back under them; a gauge of a small cell for 0 and ten cells, a tap giving a value and the same tap clearing it, unsaid until then and 0 a rating; digits, + for 10, the arrows and Delete on the keyboard; a word beside the number after Borg's CR10 (moderate, hard, very hard); a concrete question in each, feelings asked about through what stirs them; what was felt before after the same task, else its kind, shown faintly on unsaid tiles and taken by "Looks right" (FeltIndex::proposal), never written until then; saved as each value is given. Once a cost is said, "What it takes" follows them, shown, not chosen (light up to 3, usual to 6, heavy from 7; gives back with a gain of 5 or more and no cost above 3). A task is as heavy as its highest cost (demands.rs) |
built, and used by the plan (capacity.md): what you said after a task planned over what you forecast; a daily budget per cost and in total learned from your days and their outcome (raised slowly after a stable week, lowered at once after a day too much that followed a full one, held after three bad days in seven, never above the heaviest good day of the last thirty plus a tenth); heavy then light in the day, never two heavy steps in a row; the days around a heavy appointment lighter; even days if you ask; two silent slots of time for you a day; a minimum of what gives back, learned from good days and never downward from a bad stretch; all said in words only |
A time budget near a date asked (Shovel's "cushion"): "Until Wednesday 7 October: about 30 min of steps, 3 h of room." On Now for the next date asked within a week, in a task's panel within three weeks; further away it is noise. What must be done by then counts what each task waits for and its steps (a bigger task only through them); room is each day's minutes, today's weather and days off counted. When it does not fit: "More time asked, or a lighter plan?" (plan::cushion) |
built |
| Finishing says what it freed | built |
| Capture in one line, its parse shown as chips | built, inside the window (a system-wide shortcut later) |
| Done this week, never streaks | built |
| What a task is tied to, at the point of action | built, both ways, on every object |
| A Waiting column saying what each waits for; a line past three started | built |
| Splitting a task into steps at a chosen granularity, by AI | next: steps are added by hand today |
| Company: a quiet presence, an AI at start and end, a "stuck" button to the proxy | next |
| Cues from events ("after the Porch window") rather than clocks | next |
| A calm "still relevant?" pass for long-untouched tasks | next |
| The admin window played as a routine; routines of your own (Routinery: timed steps played one at a time, the next one said before it comes) | built: Tasks ▸ Routines. One step a line with its minutes ("10 min Open the Porch", "Make tea 5"), kept in the configuration ([[routine]], so they travel with your settings). Played in a small window on top: the step, its time draining in a neutral colour, "Then: …", the routine as dots; Done, Open (what the step opens), +5 min, Skip, Pause, Stop, none counted. When the time is up it moves on by itself only if the routine says so; else it waits and says so, without a sound. The admin window's routine is made from what is there: the Porch, the plan's next step, a line where you stopped (routines.rs, RoutinePlayer.qml) |
| The day, seen (Tiimo, Structured; visual supports cut transition time, Dettmer et al. 2000) | built: Tasks ▸ The day. Today's events at their times, the steps the plan gives today laid from now into the hours of their kind (work, your admin, shown as bands), around the events, five minutes' pause after each step and around each event, a step up to an hour in one go, a longer one going on after a break; each card as tall as its text, the day scrolled to the current hour; a line where now is; the step under way marked, the next outlined; a task done today stays where it ended, ticked and dimmed (a quarter of an hour to an hour long, by its estimate); what does not fit before the day ends keeps its place in the plan, said in one line. It follows the window's one clock (qml/Clock.qml): the line moves at each minute's turn and at once when the window comes back, alone (nothing is laid again for it), and the day is laid again from now at each five minutes' turn, when it shows again and as soon as Sioul comes back, with what another device marked done or noted, and at once after any change (rule 10). A layout to look at, never a schedule: nothing is written into the tasks; a time you pin a step to is an event in a calendar ("Pinned to a time") (dayview.rs, DayView.qml). Moved by hand: a step dragged (by its card, or the time kept around it) to another time today is pinned there, its time block made or moved, as long as its card (blocks::pin): the day lays it there, its margins around it, and every other step goes around it; the plan keeps it there even when that day's room is used; Now puts a step pinned more than a quarter of an hour ahead after the others. Its time says it is held (in the accent colour). The drag goes no earlier than now, and no later than midnight. Let the plan place it (its menu: right click, or a long press let go in place) takes its block away. A block over, the task not done, pins nothing, and nothing is rewritten at midnight. A meal or a nap is moved there as on the Health page, that day's change (health.md); an event wholly today, in a calendar that can be written, as in the agenda (client.md, "Calendars"): a repeating one asks first, this time or every time. Where it goes is drawn while the hand moves, its times in a tag ("10:15–10:45"), by whole five minutes; let go, "Undo" waits ten seconds in the status line; let go where it was, nothing changes. With a mouse, press and drag (the wheel scrolls); with a finger, a long press picks it up, a plain swipe scrolls. One set of handlers for the whole day (TimeDrag.qml): the cards carry none |
| Personal "sides" offered when a dreaded step starts | next |
| Estimates corrected by the time spent | built (capacity.md): the log of time spent over the first guess on finished tasks, timed minutes counting fully and typed ones a quarter, recent tasks weighing more (half-life 4.5 days), pulled toward 1.1× until about nine tasks stand behind it, per area pulled toward yours; each task laid at its corrected length while you see your own; each day's free time at the 85th percentile of its total by a seeded simulation with a shared day effect, today's re-weighed once its first tasks are done; on request in the panel, "Tasks like this usually take about 1.3× the first guess; the plan already allows for it" |
| A weekly fresh start | next |
| Three presets instead of settings | next |
Where it stands¶
| Done | tasks as VTODO with RFC 9253 links, edited line by line; the plan (order, loops, next step, days with room, gaps, streams, days off, office days, made again every twelve hours and at midnight); Now, List, Board, Calendar; the task panel, its details then its form; a new task's full form; capture in one line; the focus window and the time log; the day's weather and "Not now" by stream; "Done for today" and quiet time; the end of the work day and of the day, with how it felt (reviews.md); office hours; the plan in your hours of each kind, around events, with pauses; the day laid out; kinds and categories edited; joy and someday; notes as a vault, edited and linked; links both ways on tasks, events, mail, contacts and notes; tasks pinned to a time by time blocks, events in a calendar ("Do at…", a drag in the day, the plan and the day laying them there); tasks, events and notes made from each other; task lists and address books created on the server; import for agents; reminders before dates asked and waits over, once each (reminders.md) |
| Next | the ideas marked "next" above; changing one turn of a repeating task; a note's history with git |
| Rule and code differ | none known: a task with margins is now kept whole by the plan as by the day |