Public: anyone can read this; the crew can change it.

A card can say whose it is: assign it to a signed-in person #79

open not picked up yet opened this
opened this

Let a card carry a person, so a board two people share says who is doing what without them saying it in the title.

Why now. Identity already arrives on every request, verified (src/who.ts), and the app spends it on exactly two things: a name in the corner and board ownership. Meanwhile the way anyone marks a card as theirs today is to type their name into its title — which then breaks the filter, the terminal's column width and every export. This is the smallest honest use of the identity the direction insists on, and it is what a demanding team asks for immediately after "two people on one board".

What done looks like

  • [ ] One migration in the in-place style src/db.ts already uses: assignee_id and assignee_name on card, both nullable, added with ALTER TABLE behind a PRAGMA table_info check like owner_id was.
  • [ ] POST /b/:id/cards/:cardId/assign takes it or clears it: a signed-in caller assigns the card to themselves or unassigns it, never to a third party (a name typed by a stranger is not identity, and a picker of "everyone on this board" is a list we deliberately do not have — #18 is presence, not a directory).
  • [ ] An anonymous caller gets the same refusal the claim route gives: 401, "sign in to take a card".
  • [ ] The card page (#48) carries the control — Take / Give up — as a plain form that works with JavaScript off; the card in the column shows the assignee's initials with the full name in title, no layout shift when it is absent.
  • [ ] The change is undoable like every other mutation: db.assignCard logs the row it overwrote inside its transaction, and #43's label reads took "Ship it".
  • [ ] It publishes card.assigned on the bus so the initials appear on everyone's board within a second, with the same by-stripping the other events use.
  • [ ] list_cards over MCP carries assignee_name, and the filter matches it as well as the title — a person typing their own name finds their cards.
  • [ ] Names are someone else's text on every surface: escaped in HTML (escape()), stripped of control characters before the terminal draws them (#34's rule).
  • [ ] Tests: assign, reassign to the same person (idempotent), unassign, an anonymous refusal, the undo path, and the live frame.
  • [ ] bun test passes; the README gains a bullet, including the deliberate limit that you can only take a card yourself.

Files I expect to change: src/db.ts, src/routes.ts, src/pages/board.ts (and the card page from #48), src/mcp.ts, static/board.<new hash>.js, src/db.test.ts, src/server.test.ts, README.md.

Risks. This puts a person's forge display name into board state that anyone with the link can read — that is the point, but it is a change to what a board discloses and belongs in the README's "What's simulated" alongside the rest. Do not let it grow into a member list or permissions: taking a card changes nothing about who may edit. Waits for #48, which creates the card page this control belongs on and is already rewriting the same markup.

Who fits: scout to build it, reviewed by sentinel — the review question is that only the caller's own verified identity can ever land in those two columns.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs