Give a column an optional work-in-progress limit — the one thing that makes a kanban board a kanban board rather than three lists.
Why. Every column today shows visible/total and nothing else. A team using this for a week wants to say "Doing holds three" and to see, at a glance, when it holds five. It is the smallest product step that makes the board a tool rather than a surface, it costs one nullable column in the schema, and it fits the app's existing shape exactly: a plain form on the column header, an undoable write, one live event, one field in list_columns.
What done looks like
[ ] One migration in the in-place style src/db.ts already uses: wip_limit INTEGER NULL on board_column, added behind a PRAGMA table_info check like owner_id was.
[ ] POST /b/:id/columns/:columnId/limit sets or clears it: a whole number from 1 to the board's card cap, or empty to clear. Validated at the boundary, refused with a sentence the way every other form is.
[ ] The column header shows it in the existing count — 4/4 becomes 4/4 · limit 3 or similar, in words rather than a symbol — and the column is visibly over limit (a border or the count's colour, no layout shift, legible in both themes and without colour alone carrying the meaning).
[ ] Never enforced. Going over the limit is allowed and says so; a board that refuses a card mid-conversation is worse than a board that shows a team they are over. Write that decision into the README so it is not later mistaken for a missing feature.
[ ] Setting or clearing it is undoable like every other mutation (logAction with the row it overwrote) and publishes column.limited on the bus so every open board updates within a second.
[ ] list_columns over MCP carries wip_limit beside card_count, so an agent can see the same thing a person does, and the tool's description says it is advisory.
[ ] The terminal shows it in the column header too — the seats stay level (AGENTS.md).
[ ] Tests: set, clear, reject zero and words and 10^9, the undo path, the live frame, and a column over its limit rendering the over-limit state.
[ ] bun test passes; the README gains a line under Columns.
Files I expect to change:src/db.ts, src/routes.ts, src/pages/board.ts, src/mcp.ts, src/tty.ts, src/db.test.ts, src/server.test.ts, README.md.
Risks. Scope: this is a number on a column, not a policy engine — no per-person limits, no blocking, no analytics. The over-limit state must not rely on colour alone (a second cue: the word, or a border), or it disappears for a colour-blind reader. It touches the column header markup that #50 is also changing (the delete confirm) and the count that #48 re-renders; whichever lands second reads the other.
Who fits:scout to build it, reviewed by juniper — small, visible, and judged by looking at a board that is over its limit.
Give a column an optional work-in-progress limit — the one thing that makes a kanban board a kanban board rather than three lists.
Why. Every column today shows
visible/totaland nothing else. A team using this for a week wants to say "Doing holds three" and to see, at a glance, when it holds five. It is the smallest product step that makes the board a tool rather than a surface, it costs one nullable column in the schema, and it fits the app's existing shape exactly: a plain form on the column header, an undoable write, one live event, one field inlist_columns.What done looks like
src/db.tsalready uses:wip_limit INTEGER NULLonboard_column, added behind aPRAGMA table_infocheck likeowner_idwas.POST /b/:id/columns/:columnId/limitsets or clears it: a whole number from 1 to the board's card cap, or empty to clear. Validated at the boundary, refused with a sentence the way every other form is.4/4becomes4/4 · limit 3or similar, in words rather than a symbol — and the column is visibly over limit (a border or the count's colour, no layout shift, legible in both themes and without colour alone carrying the meaning).logActionwith the row it overwrote) and publishescolumn.limitedon the bus so every open board updates within a second.list_columnsover MCP carrieswip_limitbesidecard_count, so an agent can see the same thing a person does, and the tool's description says it is advisory.AGENTS.md).bun testpasses; the README gains a line under Columns.Files I expect to change:
src/db.ts,src/routes.ts,src/pages/board.ts,src/mcp.ts,src/tty.ts,src/db.test.ts,src/server.test.ts,README.md.Risks. Scope: this is a number on a column, not a policy engine — no per-person limits, no blocking, no analytics. The over-limit state must not rely on colour alone (a second cue: the word, or a border), or it disappears for a colour-blind reader. It touches the column header markup that #50 is also changing (the delete confirm) and the count that #48 re-renders; whichever lands second reads the other.
Who fits: scout to build it, reviewed by juniper — small, visible, and judged by looking at a board that is over its limit.