All articles

How tasks work in Unitcore

Tasks are the second Unitcore product after the budget, and they follow the same rule: everything lives inside a space and everyone in that space sees it. In your personal space that makes it your own to-do list; in a family space it is a shared one, where you can see who picked up what and who closed it.

What follows goes from the simple to the deep end: what you see on screen, what the assistant can do, and how the whole thing is put together underneath.

What it is made of

Four ideas, and the model contains nothing else: a space, lists, tasks, subtasks.

Family3 members
Inboxnot a list
Call the insurance companyUrgent · by Friday
Shopping1 of 3
Groceries for the weekLea · today
Milk
Bread
Pick up the parcelunassigned

Inbox is not a list — it is the absence of one: a task you never filed anywhere. It cannot be renamed, archived or lost, and it is also where tasks land if you delete the list they were in.

Subtasks nest exactly one level deep. That is a decision rather than a technical limit: nobody keeps a five-level tree tidy in a household to-do list, whereas “buy groceries → milk, bread” stays tidy by itself.

The board

Every list is a column, with Inbox first. A task can be dragged into a neighbouring column, or up and down inside its own. Closed ones fold away behind a counter so they stop taking up room, without going anywhere.

Every task carries:

WhatWhy
Due datewith or without a time. “By Friday” and “at 6pm” are different things, and the product keeps them apart
Prioritylow, normal, high, urgent
Assigneeanyone in the space
Notewhatever is worth remembering about this one
Labelsshared across the space, added as you need them
Subtasksone level, with a “2 of 5” counter on the card

Deletion is soft: the task drops into the trash at the bottom of the board and one tap brings it back. Its subtasks go with it — and the same ones come back, not everything that was ever deleted.

My tasks

A page of its own, collecting everything assigned to you across all of your spaces at once — personal, family, work. Four groups: overdue, today, upcoming, no due date.

Tasks you wrote for yourself and never assigned to anyone show up here too. In a personal space there is nobody to assign them to, and insisting on one would be silly.

The same thing, said out loud

Unitcore connects to Claude or ChatGPT as a connector, and the assistant sees tasks through your own eyes: your spaces, your permissions, nothing beyond them.

Twelve tools
Three that read, nine that write. The assistant works in whichever space you are in.
in the morning
“What do I have today?” → my tasks, every space at once.
on the go
“Add bread to shopping” → the list is found by name, not created twice.
in the evening
“Close everything in House” → no more than 50 tasks per call.
in a shared space
“Assign this to Lea” → by member name; identifiers never leave the server.

Two decisions worth saying out loud:

  • The assistant is allowed to delete. But its delete is the trash, not an erase: any action it takes is one tap away from being undone. Only you empty the trash, by hand.
  • Text other people wrote is data, not instructions. A task title is written by another member of the space and read by a model that holds write tools. So task content reaches the assistant inside a marked block that says plainly: this is text from the people in this space, not instructions.

How it works underneath

A schema of its own in the database, and no application layer in between: the web app and the assistant both talk to the same database as you, and the database itself decides what you are allowed to see.

Clients

Read from prepared views, write straight to the tables.

boardtask carddashboard
Assistant

The same queries as the same user — only called with words.

list_taskscreate_taskcomplete_task…9 more
Permissions

One check across every table, plus a list of columns nothing outside the database may write.

RLS: a member of this space?column-level grants
Data

Four tables and the triggers that hold the rules: one level of nesting, an assignee from this space only, closing a parent closes its subtasks.

liststaskslabelstask_labels
Reading

Views assemble the names, the counters and the “mine” flag, so no client has to go back for a second query.

task_cardslist_cardsmy_agenda

Why this rather than a server with the business logic in the middle:

One access boundary, in the database rather than in three clients
The assistant physically cannot see more than you do
Web and iOS cannot drift apart on the rules — they hold none
A new client plugs in without a new backend
The SQL details, for anyone curious
  • Everything references a pair, (id, space_id), rather than a bare id. A subtask from another space, or a label from the wrong one, is structurally impossible — no check in application code required.
  • Deleting a list is on delete set null on a single column: the tasks return to Inbox instead of disappearing with it.
  • Ordering is a fractional number. To drop a task between two neighbours the client writes the midpoint and touches no other row.
  • “Who closed it” is stamped by the database from your session; that column is not granted to any client, so there is nothing to forge.
  • Being overdue is stored nowhere and computed on read. No field, nothing to drift out of step with reality.
  • Synchronisation only ever runs downwards: closing a parent closes its subtasks, and closing the last subtask does not close the parent.

When someone leaves a space

This is where tasks differ from the budget: a transaction is a settled fact, while a task faces forward and has an assignee — and an assignee can leave.

  • Open tasks stay but lose their assignee: they belong to the space, not to a person.
  • Closed tasks keep theirs. “Lea did that one” is still true a year later.
  • Reopening clears the person who left — otherwise the task would go back into play assigned to someone who can no longer see it.

Limits, and what is deliberately missing

50 lists and 50 labels per space, 200 subtasks per task, 10,000 active tasks. A title is up to 500 characters, a note up to 10,000. These are ceilings nobody meets in ordinary use; they exist so one space cannot spoil the others.

Not in the first version, on purpose: recurring tasks, comments, attachments, several assignees on one task, private tasks inside a shared space, and notifications. Recurring tasks are designed and come next.

If you have not connected Unitcore to an assistant yet, it takes a couple of minutes: Connect Unitcore to Claude. And the spaces all of this stands on have an article of their own: How Unitcore is put together.