Task board — migration, notifications, data, shortcuts, board and SOP findings¶
Part of task-board. Design sections for the Kanboard task board: migrating the old tasks, notifications, adding tasks, data, home shortcuts, the board views and SOP findings as tasks. Text moved verbatim from task-board; references such as "above" and "below" point into that note or its sibling files.
Migrating what we already have¶
The 112 tasks in ~/.local/state/assistant/assistant.sqlite move across via JSON-RPC, one
project per department, source/source_ref preserved in task metadata. Then:
tasks.pyin the assistant stops being a store and becomes a thin client.- The admin Tasks card points at Kanboard rather than duplicating its CRUD.
tasks-exportkeeps writing~/Notes/tasks.md, now reading Kanboard — the plain-text mirror in the vault is the copy that survives the server, and it is not negotiable.- The old sqlite table is left in place, read-only, until the mirror has matched for a week.
Notifications¶
Use Kanboard's, do not build one. It has per-user notification settings out of the box: email or web, and a filter for all tasks in my projects / only tasks assigned to me / only tasks I created. Wired to Resend over SMTP, which we already pay nothing for.
What that gives immediately, with no code:
- assigned a task → email
- a task you own is commented on, moved, or closed → email
- Kanboard's daily
cronjobcommand → overdue task notifications, plus recurring tasks
What it does not give, and we add:
- "Due soon". Kanboard notifies on overdue, which is already too late. A small morning digest (the one planned for Phase 4) reads the API and mails each person what is due today and this week, one message rather than a stream. This is the reminder that actually works.
- Push to a phone. Kanboard webhooks can drive
ntfyfor anyone who wants it on their phone rather than in their inbox. Optional, per person, and worth offering to Yara — she lives in a messaging app, not an email client.
Rules so the mail stays worth reading: default every new person to tasks assigned to me, never all activity; the digest is one email a day, not one per task; and nothing sends from a noreply address — mail comes from the shop address so a reply reaches a human.
Adding a task by hand¶
Four doors, one register behind them. Nobody should have to learn Kanboard to raise a task.
- The home board — a + Task button next to the lists. A short form: title, department (defaults to yours), assignee (defaults to nobody), due date, priority. Posts through JSON-RPC. This is the door most people will use, and it is deliberately smaller than Kanboard's own form.
- Kanboard itself — the full board, drag-and-drop, columns, comments, attachments, subtasks. For whoever wants the real thing. Linked as a tile.
- The assistant — "add a task for Purchasing to re-price the LCSC line by Friday".
create_taskalready exists and already drafts-then-confirms; it gets repointed at Kanboard. Useful on a phone, where a form is a chore. - The SOP audit and friends — automatic, covered below.
Whichever door, the same minimum: a title that says what done looks like, and a department. Assignee and due date may be empty — an unassigned task in the right team's column is honest, and a fake owner is not.
Data¶
Kanboard's own task fields cover title, description, due date, priority, assignee, column and project. What it has no first-class notion of, we keep in task metadata (its key/value store, reachable over the API):
| Column | Why |
|---|---|
department |
the project already encodes it; mirrored in metadata so exports do not have to resolve project ids |
ai_state |
queued / proposed / applied. Kanboard has an assignee but no notion of handing work to a machine |
dedupe_key |
UNIQUE, nullable. The whole automatic-task mechanism depends on this |
accepted_until |
a finding we have consciously decided to live with, and when to re-ask |
The record Angel asked for — who closed it, how long it took — is Kanboard's own activity stream plus its time tracking, which is one of the better reasons to have adopted it. We read that stream rather than keeping a parallel log. The one thing we log ourselves is the AI proposal trail (proposed / reviewed / applied, per item, with the deciding person), because that is ours and has no home in Kanboard.
Shortcuts: the home page as the one front door¶
Today's tiles are hardcoded and everybody sees all eight, including the ones they cannot
open. Once home is served by the assistant service it renders from each person's
tiles: list in departments.yml, and the list grows to cover the outside services we
actually use — the things Angel currently reaches by hunting a bookmark.
Two kinds of tile, and they should look different:
- Ours — behind the Access gate, one Google login already spent: ERP, Assistant, SOPs, Reports, Admin, Vault, NAS, Sandbox.
- Outside — someone else's login, opened in a new tab. Grouped under a quieter heading so nobody thinks the gate covers them.
Outside services worth a tile, from what is actually configured on this server
(~/.config/) and in the project notes:
| Tile | Who needs it |
|---|---|
| Business Gmail / Google Workspace admin | Administration, Sales |
| Cloudflare dashboard (DNS, Pages, Zero Trust, R2) | Administration |
GitHub — EmbeddedEra org |
Engineering, Administration |
| DigiKey · Mouser · LCSC · JLCPCB | Purchasing, Engineering |
| eBay Seller Hub · Amazon Seller | Sales |
| Resend (email delivery) | Administration |
| Uptime Kuma | Administration |
| The public site + the quote inbox | Sales, Administration |
And one new one of ours: a Notebook tile for the plans, decisions and hardware notes published from the vault — see notebook-site.
Rules for the tile list, so it stays honest:
- It lives in
departments.ymlnext to everything else that decides who sees what. One registry, not a second list in the HTML. - Every tile says which host it goes to, as they do now, and outside tiles are marked as outside. No pretending a third-party login is covered by ours.
- A tile a person cannot open is not shown. Half of what makes the current page feel like a patch is offering people doors that are locked.
- LAN-only tiles (the NAS) keep the existing shop-network-only treatment.
The board¶
Per person, three lists (stacked on a phone, columns on a laptop):
- Yours — assigned to you
- Your team — your departments, unassigned or on someone else
- Due and overdue — across your departments, overdue first and in red
Each row: title · department chip · due date · who has it. Row actions: Done (demands a note, same as the admin card already does), Reassign, Due date, Hand to AI. One + Task button. Administration gets a fourth view: everything, plus closed history and the numbers.
Phone-first at 375 px, three-state theme, Home link, brand tokens — the house rules for internal pages, no exceptions for this one.
SOP findings become tasks¶
sop-audit already emits stable check ids (SOP-002.no-image) with a count and a sample.
That is the whole hook.
- One task per failing check, never per failing item. 43 parts with no image is one task that says 43, not 43 tasks. The sample goes in the detail and the count updates.
dedupe_key = "sopaudit:<check_id>". Each nightly run: failing and no open task → create; failing and already open → refresh count and detail, leave the due date and assignee alone; passing and open → close it automatically, actorsop-audit. The board empties itself as the shop gets fixed, which is the only way people keep trusting it.- Routing needs no new registry. Each check carries its SOP number; each SOP's
front-matter
owneris already a department. Finding → SOP → owner → team. - Severity sets priority sets the default due date (high 7 days, normal 30, low none), from one dict that lives next to the check table.
- Accepted risk is mandatory. A finding we have decided to live with gets a note and an expiry, and the audit will not recreate it until then. Without this escape hatch a permanent nag trains everyone to ignore the board — that is what kills audit dashboards.
The same hook takes any source with stable keys: backup canaries, the Access drift alert
from onboard access-sync, SMART warnings. Worth naming now, not worth building yet.