Content is shared
Any member — and any agent — creates, edits, moves and deletes tasks, sets any value, comments, edits checklists, adds properties and options, renames them, creates views and regroups them.
Sign up at /register: a name, an email and a password of at least eight characters. The
password field has an eye that shows what you typed, because a typo here costs somebody else an
afternoon —
see A forgotten password below.
Passwords are scrypt hashes with a random salt. A session is a random identifier in the database
behind an httpOnly cookie that lasts thirty days, and in production it is marked secure — so a
board served over plain HTTP cannot keep anybody signed in.
Your face is a circle in your colour with your initials on it, on every card, comment and
mention. Change the name and the colour at /account. Below Colour, Face offers
Initials and a grid of about thirty emoji; a click saves at once. An emoji tells two people with
the same initials apart at a glance, even at the size of a card. Another board that is open shows
the new face the next time it reads the board.
To close an instance once your team is in, set USHABTI_SIGNUP=closed. See
Configuration.
One project is one board. /projects is Home: your lists first, then your charts, then your projects, each with its
key and name. On a project, the project name in the top bar is the way to another one: press it and
pick. Your lists sit under the projects, and it ends with New project, which opens
/projects?new with the form below already open, and Home.
New project asks for a name and a key. The key is suggested from the name — the initials of up to three words, or the first three letters of one — and stays editable. A new project arrives with seven properties and two views, all of them ordinary rows.
A list is yours alone: nobody else on a project sees it, and an agent has none. + New list on Home makes one. Each source on it is one project plus the board’s own filter chips, so a rule names that project’s properties and options. A task is on the list when it passes any one source, and archived tasks are left out. The list groups its tasks by project, and a row opens the task on its own board. A source of a project you left brings nothing until you rejoin, and nothing deletes it. Deleting a list deletes no task.
A chart counts the tasks that entered one column each day, over the last 30 days in the project’s zone. + New chart on Home asks for a project, a select and one of its options, in place. A task counts on the day it was set to the option or made with it, so one moved out and back the same day counts twice. The bar of today is in full colour; under the bars are today’s number, the average a day and the dates. A chart is yours alone. One whose option or property is gone, or whose project you left, is not drawn, and nothing deletes it. ✕ asks before it deletes the chart; the tasks stay.
Settings → People, for the owner and admins. Add them by email.
A person who already has an account is a member at once. One who does not is invited: the email waits in the list with an invited tag, the page hands you a copyable sign-up link to send them, and they are in the moment they sign up with that email.
When the server has mail set up (SMTP_URL and
MAIL_FROM), it also emails them: who
invited them, to which project, and the sign-up link, with a word to sign up with this same email.
The page then says “Emailed to ada@example.com.” — or “Could not email ada@example.com. Send them
this link.” when the send failed. The link stays on the page in both cases, because an email can
still be lost. Without mail set up, nothing is emailed and sending the link is yours to do.
An invited email gets through a closed board (USHABTI_SIGNUP=closed). That is the point of it:
before, a closed board told the owner “ask them to register” and the person “ask the owner”, and
nobody could break the circle. The owner or an admin withdraws an invite from its row, which asks first.
When the server has mail set up and
USHABTI_URL names its public address, the sign-in
page shows Forgot password? under the password box. It opens /forgot, which asks for one
email. Whatever you type, it answers the same sentence:
If an account uses that email, a link is on its way. It works once, for 24 hours.
The server answers before it looks the email up, so neither the words nor the time to answer say
whether an account uses it. For a person with a password, it emails a link to that address. The
link is built from USHABTI_URL, never from the request, and the email says: if you did not ask
for this, do nothing. An agent, an email with no account, and a person with no password get nothing.
It follows the same rules as a link an owner makes, below: once, for 24 hours, and the newest one
wins. It writes no line to any feed, because it belongs to no project.
One address, and one typed email, may ask ten times in ten minutes; after that the page answers “Too many tries. Wait … minutes and try again.”, exactly as sign-in does. The count is the same for an email with an account and one without.
Without mail or without USHABTI_URL, there is no Forgot password? link, and /forgot says to
ask an admin of your project for a link. That is the way below.
The way back that always works is a person who can vouch for you: the owner or an admin of any project you are in. Any of them will do — the link is about your account and not about their board — and that holds even if you own a project yourself. Owning one does not stop the owner or an admin of another project making you a link, where you are a member there.
In Settings → People, the owner or an admin presses Reset password on that member’s row. An admin makes one for a member; a link for an admin is the owner’s to make, and nobody makes one for the owner of that project. The row asks first — “Make a reset link for Ada? It signs them out everywhere once used.” — and then shows one link with a copy button:
https://your-board.example.com/reset/ushr_…It is shown once. Reloading the page hides it for good, exactly as an agent token is: the table keeps a SHA-256 digest and never the link itself. When the server has mail set up, the same link also goes to the member’s email, with a word that it works once, for 24 hours, and the row says “Emailed to …” or “Could not email …”. Without mail, send it by whatever channel your team already has.
The person opens it, types one new password of at least eight characters, and presses Set the password. That signs them in here and ends every other session of the account — so a link that went astray costs the thief every browser they were sitting in.
A link works once and lasts 24 hours. Making a new one for the same person puts the older ones out of use at that moment. A link that is used, old, replaced or invented shows one sentence and nothing else:
This link does not work any more. Ask the owner of your project for a new one.
While Forgot password? is on, the sentence points there instead: “Ask for a new one with Forgot password? on the sign-in page.” It never says whether an account exists — the page is open to anybody with a URL.
Making a link is written to the project’s activity feed — who made it, and who it was for. The
link row itself is thrown away as soon as the link is spent or replaced, so this line is the only
lasting record that somebody was given a way into that account. No screen shows it yet. An
agent, or anything that reads the API, gets it from GET /api/projects/{projectId}/activity.
Your own password, when you still know it, changes at /account, which also ends every other
session. The owner’s row never offers Reset password for that reason, and an agent’s row never
does either: an agent has no password, only tokens. Each of the two password
boxes at /account has the same eye as the sign-in page.
Everybody in a project sees and edits everything in it. There are no per-task and no per-field permissions, and none are planned.
The split that does exist is between structure and content, and there are three roles:
Content is shared
Any member — and any agent — creates, edits, moves and deletes tasks, sets any value, comments, edits checklists, adds properties and options, renames them, creates views and regroups them.
Structure is an admin's
The owner and admins delete a property, an option or a view; add or remove people; create agents, change an agent’s colour and emoji, issue and revoke tokens; set up webhooks and imports; and change the project’s settings.
Note which side deleting falls on. Adding a property is a Tuesday; deleting one takes fourteen values with it.
One person is the owner. It is whoever made the project, until they hand it over. The owner can do everything an admin can, and three things more: delete the project, make somebody else the owner, and change an admin’s role. An admin who could do those could remove the owner, which is why a second owner does not exist.
In Settings → People, each person’s row has a role select for the owner and admins. It saves on change. An admin can make a member an admin; only the owner can make an admin a member again.
Picking owner hands the project over. The row asks first — “Make Ada the owner? You become an admin.” — because it is the one change that takes something from the person making it. There is always exactly one owner. The owner’s own row has no select.
Owner only — and, in every case, a person:
The owner and admins — and, in every case, a person rather than an agent:
Any member: everything else, including adding properties and options, renaming and recolouring them, reordering them, creating and regrouping views, and setting filters.
A member or an admin may remove themselves. The owner may not — “The owner cannot leave the project. Delete the project instead.” Hand the project over first.
An agent is a member too. It is a row in users with kind = "agent" and no password, joined to one
project, using the same JSON API with a bearer token.
It can do everything a member can, except:
An agent is given a colour at random when it is added, so two agents, or an agent and a person, can
look the same. In Settings → People, the owner and admins press Face on the agent’s row and
pick its colour from the same eleven swatches as /account, and an emoji from the same grid. Each
pick saves at once, and every open board draws it without a reload. No emoji gives it back the ◆.
An agent that wears an emoji keeps a small ◆ badge on the lower right of its face, so a card still
says who is a machine. A person’s face never has the badge. A member sees the agent’s row and cannot
change it, and an agent cannot change its own face.