Skip to content

Task board — one company to-do list, by department, on the home page

Status: partly implemented; historical plan below. Verified 2026-09-16: Kanboard is live and ~/assistant/home.py serves the live Home page; the full task board is in Kanboard. The original phase descriptions and older blockers below are historical, not a current deployment checklist. Use the live register and dated Log for remaining work; see ai-capacity for the current operating plan.

What Angel asked for

Open home.embeddedera.com, and because the gate already knows who you are, your tasks are right there: yours, your team's, what is overdue. Assign a task to a person or a group, give it a due date, put it in a calendar, close it and keep the record of who closed it and how long it took. SOP audit findings should become tasks the same way, routable to a team. And a button on any task that hands it to the AI to just fix.

The one decision that shapes everything else

Home stops being a static page and moves onto the assistant service, the way chat. and admin. already are: home.embeddedera.com → 127.0.0.1:8200, its audience added to CF_ACCESS_AUD. Reasons, in order of weight:

  1. A board scoped to the viewer needs verified identity server-side. The service already does this properly, from the signed Access JWT. A Pages site would have to fetch cross-origin into chat. with credentials: 'include' — the feedback modal proves that works, but it fails on first visit if the browser has no Access cookie for that audience, and a home page that intermittently says 401 is worse than no board.
  2. departments.yml already has a tiles: list per department and the static page ignores it — everyone sees all eight tiles today, including ones they cannot open. Moving home onto the service fixes that in the same pass, for free.
  3. One fewer deploy path. home-deploy and the Pages project retire.

Cost: if the server is down, home is down. Accept it — every tile on that page points at the server anyway, so a static home during an outage is a page of dead links.

Decided: adopt Kanboard (2026-09-13)

Angel's call, against my recommendation to extend our own register, and it settles the open question above: the kanban board itself is wanted, not just a list on the home page. On that reading the trade changes — a board UI, an iCal feed, an activity log and a built-in email notification system all arrive for free, and the sync script becomes a fair price rather than a needless one.

Kanboard: MIT, PHP + sqlite, ~128 MB, on this server as a container behind the existing gate. Everything below is written for that.

The two things this decision obliges us to get right

1. The header must not be forgeable. Kanboard trusts REMOTE_USER (REVERSE_PROXY_AUTH=true, REVERSE_PROXY_USER_HEADER). Nginx Proxy Manager sets it from the verified Cf-Access-Authenticated-User-Email — and must strip any inbound REMOTE_USER and Cf-Access-* first, in the same custom location block, not at server level. We have already been bitten by exactly this: a proxy_set_header at server level is not inherited once a location sets its own. Anyone on the shop LAN who can reach the container directly would otherwise be whoever they claim. Bind the container to localhost and treat this as the security review item for the whole phase.

2. Departments must not become a second registry. departments.yml stays the one file that decides who is what. onboard grows a Kanboard reconcile step alongside the existing Access one: departments become Kanboard groups, each group gets its project, people are added and removed to match the registry, and a drift alert fires when they disagree — the same self-reconciling pattern that fixed the Access gate. Never hand-manage users inside Kanboard's admin.

Auto-provisioning must also set each user's email address on creation, not just their name — Kanboard's notifications are worthless to a user with no email on file, and REMOTE_USER gives us the address for free.

What stays ours

Kanboard holds tasks and sends mail. It does not hold: the home board's rendering, the per-item AI proposal review, the proposal and outcome reports, the vault mirror, or the Grafana panels. Those read and write through its JSON-RPC endpoint (single endpoint, not REST — more wiring than a REST API, entirely workable).

Tweaks stay plugins. Template forks mean owning a merge conflict at every upgrade, and that is how a free tool becomes the most expensive thing on the server.

Moved out (2026-10-19, to keep this note under 400 lines)

Text moved verbatim; nothing was removed.

  • task-board-design — migrating the 112 tasks, notifications, adding a task by hand, data fields, home shortcuts, the board views, SOP findings becoming tasks.
  • task-board-ai-handoff — Hand it to the AI (proposal, per-item review, apply), dates and calendars, record and reporting.
  • task-board-sop-and-gaps — SOP-017 Task Register plan and the four SOP amendments, and the twelve gaps found on review (2026-09-13).
  • task-board-closeout — Close-out verification (2026-09-14): Review column, Verify block, task-verify loop, source table, intake close-out mode, order and decision.
  • task-board-filtering — Filtering and scope: scope selector, filters, URL state.

Kill criteria

Every new component gets one before it is built, or the estimate quietly becomes a commitment.

  • Kanboard — six weeks. If the board is not being opened without being asked, go back to the list on the home page. The vault mirror and the read-only sqlite keep that exit cheap.
  • Home on the assistant service — this one has no clean exit once the Pages project retires, so the criterion is a gate rather than a rollback: it does not ship until the per-department tiles work and the board renders correctly at 375 px. If it cannot do both, home stays where it is.
  • The AI proposal pipeline — three job classes, thirty proposals. If more than a third of proposed items are rejected rather than accepted or edited, the pipeline is generating work instead of saving it. Stop and fix the class, or drop it.
  • The notebook site — see notebook-site.

Build status (2026-09-13)

  • Done: departments split into functions with the Quality function tags, verified with no effective permission change; SOP-017 written and published with its four audit checks and the four amendments; kill criteria for every component; the whole plan loaded into the task register.
  • Blocked, not started: phase 1 itself. Creating tasks.embeddedera.com — DNS, tunnel route, Access app, proxy rules, a new container — was refused as too much to do unattended on a live server. Nothing was created. It needs a session Angel is watching, or his hands. The plan below is unchanged and ready to run.

Order

Phase What Rough
1 Kanboard up behind the gate, header hardening, onboard reconcile, Access app + registry token, map card, backup + restore rehearsal, monitors, migrate 112 tasks a day and a half
2 Home onto the service: per-department tiles, outside shortcuts, the board, + Task a day
3 SOP findings → tasks, with dedupe, auto-close and accepted risk half a day
4 Notifications: Resend SMTP, defaults per person, overdue cronjob, morning digest, iCal half a day
5 Hand to AI: sandbox run, proposal report + email, per-item review, apply with outcome report two days
6 Grafana panels, SOP-017, the four amendments, new audit checks a day

Phases 1 and 2 are the ask. Phase 3 makes the board fill itself. Phase 5 goes last, once the board is trusted — an AI button on a list nobody believes is a way to make bad changes faster.

Related: meetings-and-tasks, roles-and-skills, reporting.

Log

  • 2026-09-13: plan written.
  • 2026-09-13: Angel chose Kanboard over extending our register — he wants the board itself. Plan rewritten around it; notifications and manual entry added.
  • 2026-09-14: close-out verification planned — Review column, Verify block, task-verify loop with bounce-back, source table with record.yml, intake close-out mode. Angel's rule: a Done comment is a claim, recheck it, reject with specifics, keep the source.
  • 2026-09-14: decided — human verification of a 'cannot tell' is someone in the same department other than the closer; falls through to Administration when there is nobody else.
  • 2026-09-14: steps 1–2 of Close-out built and live; 177 verified by task-verify itself, 178 left for the timer. Steps 3–5 (record.yml + backfill, intake close-out mode, dashboard) remain as tasks 179–181.
  • 2026-09-14: step 4 (intake close-out mode) live in production; tested pass and bounce paths on a dev-identity copy. Step 5 (metrics, dashboard, digest lines) is task 181.

  • 2026-09-16: Corrected stale opening status after querying live Kanboard and inspecting Home source. Capacity collector and Home card requested as task #235; no completed claim yet.