The product
Everything it does, and where each thing lives
Hubtask is one model with a lot of surface. This page walks the surface — what you can put on a task, how you look at a list, who gets in and how, what happens while you are asleep, what it does when the network is gone, and how an installation is run. What is decided and still being built is marked Planned.
Hub Collection Task Work package Activity
The hierarchy
What each level carries
The five levels are not five entities. They are one item with a capability profile, and the profile decides what the level accepts. A field the level does not carry is refused with a named error rather than silently dropped — so a client, a script and an agent all find out the same thing at the same moment.
| Capability | Task | Work package | Activity |
|---|---|---|---|
| Completion | yes | yes | yes |
| Due date | yes | yes | yes |
| Reminders | yes | yes | yes |
| Assignment | yes | yes | one assignee |
| Several members | yes | yes | no |
| Notes, labels, comments | yes | yes | no |
| Attachments | yes | yes | no |
| Custom fields | yes | yes | no |
| Bucket on a board | yes | no | no |
| Cover (colour or image) | yes | no | no |
| Recurrence | yes | no | no |
| History | yes | yes | compact |
A workspace may narrow a profile, never widen it past the system boundary. If your team decides activities carry no due date, that is a setting. If somebody wants a sixth level, that is a profile entry and a permitted-child-type change — no schema migration, no API break.
Looking at work
Four layouts and a query language
List
Collapsed or expanded, with the subtree visible where you want it and folded where you do not.
Kanban
Buckets under a collection, with a work-in-progress limit and a done column that are announced rather than enforced — the server never refuses a card for crossing a limit somebody set as a reminder to themselves.
Timeline
A span where an item has a start and a due date, a point where it only has a due date, and a list beside the axis for everything undated — because hiding the undated would be a filter nobody chose.
Saved views
A query, a layout hint and a share setting, stored and re-openable. Exportable as CSV, JSON or ICS.
The query language
Filtering is a composable expression over fields the installation actually has — including the custom fields you defined — with comparisons the server declares rather than a client guessing. It is the same language behind a saved view, an export, an automation condition and an agent’s search.
No byte of a request ever becomes SQL text. That is not a habit; it is a gate in the build.
api-guidelines.md · the query DSLSearch
Full-text search across titles, notes and comments, in the language of the content. Where the database offers the vector extension, a semantic pass joins it and the two are ranked into one page — the words winning over the meaning, and one cursor for both.
Where the extension is absent, search is lexical, complete, and says so through the capability manifest rather than failing.
ai-first.md §2 · hybrid searchTime
Dates that survive a time zone change
- All-day and timed due dates A day is a day and a moment is a moment; they are different things and are stored differently. An item may carry its own time zone.
- Recurrence by RFC 5545 Real RRULEs, repeating either on schedule or on completion, with the transition across daylight saving covered by tests rather than by hope.
- Reminders, relative or absolute “Half an hour before it is due” or a fixed moment, several per item, delivered when they are due — with punctuality as a measured objective, not a promise.
- Templates A whole tree of tasks, work packages and activities with relative dates, stamped out in one call and anchored to a date you name.
- Calendar feeds A revocable ICS URL for any saved view, readable by any calendar application. The URL is the credential, it is shown once, and it can be withdrawn.
- CalDAV, both ways Tick a task off or move its date in the calendar app you already use, and the change goes through the same rules as one made in Hubtask.
- Live updates A server-sent event stream, so a second window and a second device do not disagree about what is done.
Working with other people
Collaboration and content
Members and assignment
An assignee or a set of members, depending on the level. Automatic assignment by policy where you want the system to choose, and a named refusal when no candidate can take it — never a silent drop.
Comments
Threaded, editable, with “removed” as a visible state of its own rather than a hole in the conversation.
Attachments and covers
Files go to object storage or the local volume by a presigned upload the server never carries the bytes for, and are usable only after a confirmation step that reads them back. A cover is a colour from the palette or an image.
Custom fields
Eight kinds of field, defined per collection, filterable in the query language like any built-in field.
Roles
Seven roles across four scopes — workspace, hub, collection, item — with an auditor role that reads the trail and the configuration and nothing else. Permission is resolved in one place, never in an adapter and never in a repository.
domain-model.md §3 · the role matrixHistory
Every change on an item, with the actor and what changed — and for activities, a compact form, because a tick does not need a paragraph.
Who gets in
Signing in, on your own rules
The password rule
Eighteen switches in three groups — the password, the second factor, the session — set by the installation with a lock where it decides, and tightened by a workspace where it may. Shipped at what NIST advises: length over composition, common passwords refused, no forced expiry. The rules show under the field as you type, in your language.
ADR-0068A second factor, and the way back
An authenticator app, required of administrators or of everybody. Ten recovery codes you can copy and replace. A forgotten password is reset by mail, and the reset still asks for the second factor. Every session is listed and can be ended.
Google, Microsoft, your own directory
Several providers per workspace, each with its own button. A provider admits by directory, never by the text of an address, and connecting it to an account that already exists asks for that account’s own proof first. An installation can offer providers to every workspace without showing any of them a secret.
ADR-0071Tokens and apps
Personal access tokens with scopes and an expiry, service accounts for machines, and third-party apps a person lets act for them through OAuth — and takes back.
Next
Planned Passkeys. Terms of use agreed at the invitation and again when they change. Accounts for a child or a grandparent without a mail address. Private hubs another administrator cannot open. People arriving from a directory landing with a role.
In, out, and back
Nothing is stuck, nothing is lost
- Imports From a spreadsheet, Trello, Google Tasks or Microsoft To Do, with a report of what came in and what was refused and why. Running the same import twice creates nothing twice.
- Trash and archive A deleted hub, collection or task waits in the trash, thirty days by default; finished work is archived rather than deleted, and both come back with their history.
- Retention you can see coming A rule shows what it would remove before it acts, warns the people whose work it touches, and a legal hold stops it.
- Backups that are checked Encrypted, to your own target, on a schedule with generations, and opened by the code that would restore them. Restore the whole workspace or bring one hub back.
- Mail when it matters When work lands on you, before something is due, when something you set up stops working — and each person chooses which mails they get. Planned Channels other than the mailbox, and rules that tell people something.
- Small things that save time Duplicate a task with its subtree, change many entries at once, see what is on you when you arrive, a short tour on the first visit, and a small celebration when work gets done — switchable per account.
While you are away
Automation, intake and agents
Rules
Triggers on what happens, conditions in a real expression language, and actions drawn from the same catalogue a person uses. A dry run shows what a rule would do before it is allowed to do it, and loop and throttle protection stop a rule from feeding itself.
automation.mdThe inbox for anything unsorted
Quick capture, an inbound webhook and an e-mail address that can be rotated — everything arrives in one place and becomes work when somebody converts it. Optionally with a suggestion attached, which changes nothing until it is accepted.
Webhooks out
Signed subscriptions with retries and a dead-letter path, carrying published CloudEvents schemas, a secret that can be replaced without dropping a delivery, and a replay of what a server missed. Connectors for n8n and Zapier are generated from the same contract, built and tested, and published with the convergence milestone.
AI, entirely optional
Suggestions for the inbox and for breaking a task down, summaries, semantic search — with the provider behind a port, configurable per workspace, and Ollama on your own machine as a first-class choice. Switched off, none of it is there, and the rest of the product is unchanged.
Planned A model the provider offers, switched on with one click and counted against a budget; and each person keeping their own content out, unless the workspace names a legal basis for AI as part of everybody’s work.
ai-first.md §2Away from the network
Offline, without losing what somebody else did
The web app keeps a copy of your workspace in the browser and goes on working when the connection drops: changes wait in a queue and are sent when it returns, and the devices you used are listed and can be forgotten. The data model has carried what this needs since the first migration — a change log, tombstones, a clock per field change and fractional indices. Planned The installed desktop and mobile apps, and reminders, recurrence and templates changed while offline.
No client merges. Merging happens on the server, per field, with conflict-preserving rules — last write wins where that is right, an order-preserving set where it is not, a fractional index for position. Two people editing the same task at the same time must not produce a lost edit and a shrug, and that is a property of the merge rather than of any one client.
offline-sync.md §4Multilingual by construction
The backend never emits display text — it emits a message code and parameters, and the client renders it. That is what makes a new language a catalogue file rather than a release, and it is why right-to-left and a forty-per-cent-longer German string are requirements on every client rather than a later project.
i18n-l10n.mdRunning the installation
One level above every workspace
For whoever runs Hubtask for others — and, on a private installation, simply one more section of the administration.
Operators, and an hour at a time
A register of the people and machines who may run the installation, separate from every workspace’s administrators. A person raises their own session for one hour after a fresh proof, and every start and end is in the installation’s journal.
ADR-0070Defaults with a lock
Sign-in rules, legal texts, limits and language defaults set once for every workspace —
each with a lock that decides whether a workspace may change it, and a screen that says
which level decided. From the dashboard, from hubctl, or from a file.
The dashboard
Workspaces and their state — create, suspend, resume, delete, export — limits per workspace, the health report, the journal, and key rotation with a census of what moved. Numbers and states, never a workspace’s content.
Next
Planned The first start in the browser with a one-time code. AI models the installation offers, with a budget per source. Plans with their own limits, features and locks. Events that tell a purchase platform what happened. A workspace’s own domain.
The order they come in