@lovek4d/kickflip 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CONTEXT.md +170 -118
  2. package/README.md +23 -14
  3. package/SKILL.md +40 -38
  4. package/bin/doctor.mjs +4 -4
  5. package/bin/install.mjs +3 -3
  6. package/bin/kickflip.mjs +34 -26
  7. package/bin/wait-events.mjs +2 -2
  8. package/board/arch-review.mjs +1 -1
  9. package/board/auto-review.mjs +2 -0
  10. package/board/bin/board.mjs +213 -74
  11. package/board/domain.mjs +8 -5
  12. package/board/finish.mjs +4 -0
  13. package/board/headless.mjs +4 -0
  14. package/board/merge3.mjs +1 -0
  15. package/board/on-host.mjs +1 -1
  16. package/board/permissions.mjs +2 -0
  17. package/board/public/app-arch.js +2 -2
  18. package/board/public/app-asks.js +39 -103
  19. package/board/public/app-banner.js +2 -2
  20. package/board/public/app-cards.js +166 -73
  21. package/board/public/app-core.js +2 -23
  22. package/board/public/app-header.js +12 -5
  23. package/board/public/app-lanes.js +201 -47
  24. package/board/public/app-needs.js +2 -1
  25. package/board/public/app-reader.js +174 -0
  26. package/board/public/app-snapshot.js +2 -2
  27. package/board/public/app-threads.js +53 -42
  28. package/board/public/app.html +4 -1
  29. package/board/public/app.js +78 -96
  30. package/board/public/attach.js +39 -3
  31. package/board/public/dialogs.js +59 -14
  32. package/board/public/hub-kit.js +9 -6
  33. package/board/public/hub.css +6 -18
  34. package/board/public/linear-key.js +6 -4
  35. package/board/public/log.html +48 -0
  36. package/board/public/new-task.js +121 -0
  37. package/board/public/prompts.js +9 -8
  38. package/board/public/prototype-kit.js +6 -6
  39. package/board/public/prototype-switcher.js +13 -5
  40. package/board/public/prototype.html +1 -0
  41. package/board/public/router.js +8 -7
  42. package/board/public/rules-editor.js +3 -4
  43. package/board/public/shell.js +24 -6
  44. package/board/public/sidebar.css +22 -1
  45. package/board/public/sidebar.js +64 -31
  46. package/board/public/style.css +245 -64
  47. package/board/public/toasts.js +2 -2
  48. package/board/public/ui-cards.js +205 -75
  49. package/board/public/ui-enums.js +6 -5
  50. package/board/public/ui-header.js +10 -10
  51. package/board/public/ui-hub.js +4 -4
  52. package/board/public/ui-markdown.js +1 -1
  53. package/board/public/ui-order.js +9 -6
  54. package/board/public/ui-page-header.js +10 -7
  55. package/board/public/ui-patch.js +53 -0
  56. package/board/public/ui-phase-bars.js +17 -0
  57. package/board/public/ui-prompts.js +8 -8
  58. package/board/public/ui-questions.js +61 -29
  59. package/board/public/ui-sidebar.js +54 -24
  60. package/board/public/ui-snapshot.js +20 -9
  61. package/board/public/ui-threads.js +40 -21
  62. package/board/public/ui.js +116 -18
  63. package/board/public/view-frame.js +2 -1
  64. package/board/public/view-hub-settings.js +25 -18
  65. package/board/public/view-hub.js +53 -12
  66. package/board/public/view-notes.js +1 -1
  67. package/board/public/view-questions.js +142 -62
  68. package/board/public/view-settings.js +189 -52
  69. package/board/review.mjs +1 -1
  70. package/board/server.mjs +20 -12
  71. package/board/store.mjs +15 -12
  72. package/board/tickets.mjs +3 -3
  73. package/board/worktree.mjs +21 -15
  74. package/docs/hub-session.md +4 -4
  75. package/hooks-plugin/hooks/codex-share-auto.mjs +1 -1
  76. package/hooks-plugin/hooks/watcher-stop.mjs +2 -2
  77. package/hub/board-repo.mjs +1 -1
  78. package/hub/boards.mjs +4 -4
  79. package/hub/close-board.mjs +1 -1
  80. package/hub/front-door.mjs +20 -0
  81. package/hub/github.mjs +4 -4
  82. package/hub/home.mjs +1 -1
  83. package/hub/hub.mjs +11 -14
  84. package/hub/incoming.mjs +2 -0
  85. package/hub/linear.mjs +2 -2
  86. package/hub/live.mjs +2 -2
  87. package/hub/new-board.mjs +2 -2
  88. package/hub/owner-checks.mjs +1 -0
  89. package/hub/permission-denied-hook.mjs +2 -0
  90. package/hub/pr-report.mjs +3 -1
  91. package/hub/presence.mjs +1 -1
  92. package/hub/prompts.mjs +1 -1
  93. package/hub/push.mjs +2 -2
  94. package/hub/readiness.mjs +2 -2
  95. package/hub/repos.mjs +3 -3
  96. package/hub/restart-board.mjs +1 -1
  97. package/hub/schedule.mjs +1 -1
  98. package/hub/sessions.mjs +2 -2
  99. package/hub/sw.js +1 -1
  100. package/hub/try.mjs +8 -4
  101. package/hub/usage.mjs +3 -3
  102. package/hub/views.mjs +1 -1
  103. package/package.json +5 -1
  104. package/shared/card-prs.mjs +1 -0
  105. package/shared/colors.css +5 -4
  106. package/shared/fake-gh.mjs +59 -8
  107. package/shared/owner-check.mjs +3 -0
  108. package/shared/repos.mjs +1 -1
  109. package/shared/tailscale.mjs +1 -0
  110. package/shared/usage-gate.mjs +1 -1
  111. package/board/public/view-polling.js +0 -87
package/CONTEXT.md CHANGED
@@ -7,35 +7,35 @@ Pages on Love's tailnet that Claude sessions serve, so the owner can follow and
7
7
  ### Hub and sites
8
8
 
9
9
  **Kickflip folder**:
10
- The installed npm package or the owner's Git clone used through `npm link`, supplying the running app's code and linked into Claude Code's skills by init. It is separate from the live state in `~/.claude/kickflip/` ([0101](docs/adr/0101-kickflip-ships-as-a-minified-npm-package.md)). Init supplies kickflip's status line and hooks as well as the skill links, so setup is independent of the owner's dotfiles ([0080](docs/adr/0080-kickflip-installs-its-own-status-line-and-hooks.md)).
10
+ The installed npm package or the owner's Git clone used through `npm link`, supplying the running app's code and linked into Claude Code's skills by init. It is separate from the live state in `~/.claude/kickflip/` ([kickflip ships as a minified npm package](docs/adr/2026-11-01-2247-kickflip-ships-as-a-minified-npm-package.md)). Init supplies kickflip's status line and hooks as well as the skill links, so setup is independent of the owner's dotfiles ([kickflip installs its own status line and hooks](docs/adr/2026-11-01-1322-kickflip-installs-its-own-status-line-and-hooks.md)).
11
11
  _Avoid_: live skill folder
12
12
 
13
13
  **Doctor**:
14
- The hub setup check, `kickflip doctor`: each prerequisite, installed piece and site is ok, fixable by kickflip, the owner's to fix with the printed command, optional (Codex installed and logged in, or the mattpocock skills an **architecture review** follows, installed and current) or a note (a down site the hub restarts). `doctor --fix` runs the same setup as first-run `init` and checks again; another tool's status line stays the owner's choice ([0085](docs/adr/0085-doctor-checks-and-fixes-a-hub.md)).
14
+ The hub setup check, `kickflip doctor`: each prerequisite, installed piece and site is ok, fixable by kickflip, the owner's to fix with the printed command, optional (Codex installed and logged in, or the mattpocock skills an **architecture review** follows, installed and current) or a note (a down site the hub restarts). `doctor --fix` runs the same setup as first-run `init` and checks again; another tool's status line stays the owner's choice ([doctor checks and fixes a hub](docs/adr/2026-11-01-1433-doctor-checks-and-fixes-a-hub.md)).
15
15
  _Avoid_: status (the former CLI command)
16
16
 
17
17
  **Board repo**:
18
- A project's shared checkout in `<clone>/.repos/<owner>/<repo>` for a clone or `~/.claude/kickflip/repos/<owner>/<repo>` for an installed package, chosen from the GitHub list or a pasted GitHub link or `owner/name` when making a board ([0078](docs/adr/0078-a-pasted-github-link-picks-any-reachable-repo.md)). Another host's git link makes a board on that plain git remote, cloned in `.repos/<host>/<path…>`, whose cards finish as pushed branches instead of PRs ([0127](docs/adr/0127-a-board-can-work-on-any-git-remote.md)). Each board keeps its own branch, and its builders work in separate worktrees based on that branch ([0073](docs/adr/0073-a-new-board-chooses-a-repo-and-branch.md)). Before a session starts in it, the hub marks it trusted in Claude Code's `.claude.json`; the New board tap is the consent ([0113](docs/adr/0113-the-hub-trusts-the-clones-it-makes.md)).
18
+ A project's shared checkout in `~/.claude/kickflip/repos/<owner>/<repo>`, whether kickflip runs from a clone or an installed package ([board clones live outside the package](docs/adr/2026-11-04-0103-board-clones-live-outside-the-package.md)), chosen from the GitHub list or a pasted GitHub link or `owner/name` when making a board ([a pasted GitHub link picks any reachable repo](docs/adr/2026-11-01-1307-a-pasted-github-link-picks-any-reachable-repo.md)). Another host's git link makes a board on that plain git remote, cloned in `repos/<host>/<path…>`, whose cards finish as pushed branches instead of PRs ([a board can work on any git remote](docs/adr/2026-11-02-1850-a-board-can-work-on-any-git-remote.md)). Each board keeps its own branch, and its builders work in separate worktrees based on that branch ([a new board chooses a repo and branch](docs/adr/2026-10-31-1636-a-new-board-chooses-a-repo-and-branch.md)). Before a session starts in it, the hub marks it trusted in Claude Code's `.claude.json`; the New board tap is the consent ([the hub trusts the clones it makes](docs/adr/2026-11-02-1549-the-hub-trusts-the-clones-it-makes.md)).
19
19
  _Avoid_: repo folder (for the repo choice)
20
20
 
21
21
  **Local board**:
22
- A board whose builders branch from its repo's local `main` and land there, with nothing fetched: a board `kickflip join` made, marked `local: true`, on the folder it ran in, the hub board included; and a board with neither a GitHub repo nor a plain git remote, on its session's folder (`hub/boards.mjs` `buildsLocally`). Bare `kickflip join`, run in a git repo's folder, asks for the board name, records the folder's GitHub origin and branch, marks the folder trusted for Claude Code and starts the board's session, in the background or with `--hub` in the foreground in tmux, attached to that terminal ([0143](docs/adr/0143-kickflip-join-adds-the-current-repository-as-a-board.md), [0147](docs/adr/0147-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
22
+ A board whose builders branch from its repo's local `main` and land there, with nothing fetched: a board `kickflip join` made, marked `local: true`, on the folder it ran in, the hub board included; and a board with neither a GitHub repo nor a plain git remote, on its session's folder (`hub/boards.mjs` `buildsLocally`). Bare `kickflip join`, run in a git repo's folder, asks for the board name, records the folder's GitHub origin and branch, marks the folder trusted for Claude Code and starts the board's session, in the background or with `--hub` in the foreground in tmux, attached to that terminal ([kickflip join adds the current repository as a board](docs/adr/2026-11-03-0248-kickflip-join-adds-the-current-repository-as-a-board.md), [boards run in the background, sleep and wake from the page, and the hub board runs in tmux](docs/adr/2026-11-03-0313-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
23
23
  _Avoid_: joined board, folder board
24
24
 
25
25
  **Hub**:
26
- The one server on the host that answers the tailnet address, lists every site, forwards to each, checks GitHub for the open PRs on boards' cards, and sends pushes. Changes on the hub, boards and starter sites come from the app's own pages or non-browser clients; another site's page cannot act on them ([0069](docs/adr/0069-the-hub-starts-a-new-boards-session.md)).
26
+ The one server on the host that answers the tailnet address, lists every site, forwards to each, checks GitHub for the open PRs on boards' cards, and sends pushes. Changes on the hub, boards and starter sites come from the app's own pages or non-browser clients; another site's page cannot act on them ([the hub starts a new board's session itself](docs/adr/2026-10-31-0137-the-hub-starts-a-new-boards-session.md)).
27
27
  _Avoid_: portal, gateway
28
28
 
29
29
  **Host**:
30
- The machine the hub and its sessions run on, a Mac or a Linux machine. Its **hub service** keeps the hub running: a launchd login item on macOS, a systemd user unit on Linux, chosen by `shared/service.mjs` at init; init, doctor, land's restart and uninstall all go through it ([0093](docs/adr/0093-the-hub-runs-under-the-hosts-service-manager.md)).
30
+ The machine the hub and its sessions run on, a Mac or a Linux machine. Its **hub service** keeps the hub running: a launchd login item on macOS, a systemd user unit on Linux, chosen by `shared/service.mjs` at init; init, doctor, land's restart and uninstall all go through it ([the hub runs under the host's service manager](docs/adr/2026-11-01-1542-the-hub-runs-under-the-hosts-service-manager.md)).
31
31
  _Avoid_: the Mac, server (for the machine)
32
32
 
33
33
  **Sidebar**:
34
- The list of every site beside each board and hub page: New version with Reload when the hub’s code changed since the app loaded, else, on an npm install, Update available · Upgrade while npm has a newer kickflip, which runs `kickflip update` once no builder runs ([0161](docs/adr/0161-the-hub-offers-a-newer-kickflip-from-npm.md)), then Hub, then Turn on notifications when needed, then Pages (sites that aren't boards), then Boards with their status words, lane chips, waiting counts and **context window** (its owner session's last reported percent, e.g. “62% ctx”, from `~/.claude/kickflip/context/<session>.json`, which the status line writes; dimmed with its age once ten minutes old; none on cards or for subagents). The last row of Boards is **New board**, a + tile opening a sheet that chooses a GitHub repo from the list or a pasted GitHub link or `owner/name`, then its branch, Name, optional What it’s for and Tickets (Internal · INT by default); a line under the repo field points a repo already on the host at `kickflip join` in its folder. Start is the confirm: the hub starts the board’s session itself once the request passes its checks; a muted, non-link row reads **Cloning…**, then **Starting…** until its route joins. When claude fails to start, or after 15 minutes without a join, it keeps the board's name in red with **failed to start** under it ([0069](docs/adr/0069-the-hub-starts-a-new-boards-session.md)); tapping it opens a sheet with the clone or session error line, what the start used, Dismiss and **Retry**, which starts it again from the same record ([0130](docs/adr/0130-a-failed-start-retries-from-its-sheet.md)). Hub carries notification problems and the tools’ 5-hour usage bars under its sub line, and a moon after its name while pushes are held or snoozed, whose tooltip says until when; the whole row opens the hub page and stays selected on the hub page and its settings modals. Boards and Pages stay apart wherever sites are listed. The header's logo toggles it at every width; it carries no count, and shows a plain accent dot while a new version waits. From 900px it is a rail, which its own logo collapses out of sight until the header's logo brings it back; narrower, it is a drawer. Its header reads Kickflip. Below 900px every page header is a bottom bar, and the drawer header sits at its foot under New board; desktop headers stay at the top ([0070](docs/adr/0070-phone-headers-sit-at-the-bottom.md)). In the **app shell** it is mounted once, beside every view and framed page, and a site's row swaps the view in place. `/` opens this device's **last board**, which the app shell stores as each board opens, never a page ([0050](docs/adr/0050-a-sidebar-of-every-board-replaces-the-hub-home.md), [0055](docs/adr/0055-one-app-for-the-whole-hub.md)).
34
+ The list of every site beside each board and hub page: New version with Reload when the hub’s code changed since the app loaded, else, on an npm install, Update available · Upgrade while npm has a newer kickflip, which runs `kickflip update` once no builder runs ([the hub offers a newer kickflip from npm](docs/adr/2026-11-03-1521-the-hub-offers-a-newer-kickflip-from-npm.md)), then Hub, then Turn on notifications when needed, then Pages (sites that aren't boards), then Boards with their status words, lane chips, waiting counts and **context window** (its owner session's last reported percent, e.g. “62% ctx”, from `~/.claude/kickflip/context/<session>.json`, which the status line writes; dimmed with its age once ten minutes old; none on cards or for subagents; a board not listening at 95% or more reads **context full**, and the hub board's session gets `/compact` typed into its tmux pane once ([a board session compacts before its context fills](docs/adr/2026-11-03-1823-a-board-session-compacts-before-its-context-fills.md))). The last row of Boards is **New board**, a + tile opening a sheet that chooses a GitHub repo from the list or a pasted GitHub link or `owner/name`, then its branch, Name, optional What it’s for and Tickets (Internal · INT by default); a line under the repo field points a repo already on the host at `kickflip join` in its folder. Start is the confirm: the hub starts the board’s session itself once the request passes its checks; a muted, non-link row shows its name, its three start steps (**cloning**, **starting orchestrator**, **landing it**) on the board's phase bars, and the step with its seconds, cloning with git's percent, until its route joins and the row turns into the board's ([a new board shows its start steps and live clone progress](docs/adr/2026-11-04-1914-a-new-board-shows-its-start-steps-and-clone-progress.md)). When claude fails to start, or after 15 minutes without a join, it keeps the board's name in red with **failed to start** under it ([the hub starts a new board's session itself](docs/adr/2026-10-31-0137-the-hub-starts-a-new-boards-session.md)); tapping it opens a sheet with the clone or session error line, what the start used, Dismiss and **Retry**, which starts it again from the same record ([a failed start retries from its sheet](docs/adr/2026-11-02-2006-a-failed-start-retries-from-its-sheet.md)). Hub carries notification problems and the tools’ 5-hour usage bars under its sub line, and a moon after its name while pushes are held or snoozed, whose tooltip says until when; the whole row opens the hub page and stays selected on the hub page and its settings modals. Boards and Pages stay apart wherever sites are listed. The header's logo toggles it at every width; it carries no count, and shows a plain accent dot while a new version waits. From 900px it is a rail, which its own logo collapses out of sight until the header's logo brings it back; narrower, it is a drawer. Its header reads Kickflip. Below 900px every page header is a bottom bar, and the drawer header sits at its foot under New board; desktop headers stay at the top ([phone headers sit at the bottom, with boards nearest the thumb](docs/adr/2026-10-31-1532-phone-headers-sit-at-the-bottom.md)). In the **app shell** it is mounted once, beside every view and framed page, and a site's row swaps the view in place. `/` opens this device's **last board**, which the app shell stores as each board opens, never a page ([a sidebar of every board replaces the hub home](docs/adr/2026-10-29-1639-a-sidebar-of-every-board-replaces-the-hub-home.md), [one app for the whole hub](docs/adr/2026-10-29-2005-one-app-for-the-whole-hub.md)).
35
35
  _Avoid_: hub home, switcher, nav
36
36
 
37
37
  **Switch mode**:
38
- The sidebar showing each linked row's key after s is pressed twice outside a text field: the first nine boards' numbers on their tiles, and every linked row's letter from its name, in blue, while the Boards label reads "Boards – press a key to switch" over a bar that drains, and no row moves. The next key opens that row in place; Escape, a click or 3 seconds with no key ends it. Boards claim letters first, in the order they joined the hub, so a new board never takes another board's letter ([0056](docs/adr/0056-switch-mode-letters-come-from-names-in-join-order.md)).
38
+ The sidebar showing each linked row's key after s is pressed twice outside a text field: the first nine boards' numbers on their tiles, and every linked row's letter from its name, in blue, while the Boards label reads "Boards – press a key to switch" over a bar that drains, and no row moves. The next key opens that row in place; Escape, a click or 3 seconds with no key ends it. Boards claim letters first, in the order they joined the hub, so a new board never takes another board's letter ([Switch mode's letters come from names, claimed in the order sites joined](docs/adr/2026-10-30-1102-switch-mode-letters-come-from-names-in-join-order.md)).
39
39
  _Avoid_: shortcuts, hotkeys, jump mode
40
40
 
41
41
  **Shortcuts sheet**:
@@ -43,7 +43,7 @@ The centred Keyboard shortcuts sheet over the dimmed page that h pressed twice w
43
43
  _Avoid_: help modal, cheat sheet
44
44
 
45
45
  **App shell**:
46
- The one page a browser's load of `/`, a hub page or any site's page gets, `board/public/app.html`: the sidebar, mounted once, beside one **view** at a time, and the hub's one stream, `/_hub/stream`. Following a link to a view swaps it in place, with no reload, and leaving one with an unsaved edit asks first. Every URL stays a real address. The board server answers a board's four view paths with the shell too, and the hub every load of `/_hub/`, `/_hub/settings` and `/_hub/settings/polling`, so curl and a frame get it; a frame's shell hands its URL to the app around it. While the host can't be reached, the hub's service worker opens the last shell the hub served, with its last sidebar, and each view shows its own offline state ([0055](docs/adr/0055-one-app-for-the-whole-hub.md)).
46
+ The one page a browser's load of `/`, a hub page or any site's page gets, `board/public/app.html`: the sidebar, mounted once, beside one **view** at a time, and the hub's one stream, `/_hub/stream`. Following a link to a view swaps it in place, with no reload, and leaving one with an unsaved edit asks first. Every URL stays a real address. The board server answers a board's four view paths with the shell too, and the hub every load of `/_hub/`, `/_hub/settings` and the old Polling page, `/_hub/settings/polling`, which opens Quiet hours, so curl and a frame get it; a frame's shell hands its URL to the app around it. While the host can't be reached, the hub's service worker opens the last shell the hub served, with its last sidebar, and each view shows its own offline state ([one app for the whole hub](docs/adr/2026-10-29-2005-one-app-for-the-whole-hub.md)).
47
47
  _Avoid_: SPA, wrapper, frame
48
48
 
49
49
  **View**:
@@ -51,35 +51,35 @@ One page's content in the app shell, mounted when its URL opens and unmounted, w
51
51
  _Avoid_: screen, tab, page (a page is its own document)
52
52
 
53
53
  **Page tree**:
54
- The levels back climbs in the app shell: a board, its Waiting on you, then a separately opened prototype page tied to one of its questions by `?q=`. On each, the back arrow, the browser's back and a swipe all go up one level: from a prototype to Waiting on you on its question, from there to the board, with the card still open when the owner left the board from that card's thread. However the owner arrives, by a push, a link or a reload, the levels above are written into history under the page first ([0058](docs/adr/0058-back-follows-the-page-tree.md)).
54
+ The levels back climbs in the app shell: a board, its Waiting on you, then a separately opened prototype page tied to one of its questions by `?q=`. On each, the back arrow, the browser's back and a swipe all go up one level: from a prototype to Waiting on you on its question, from there to the board, with the card still open when the owner left the board from that card's thread. However the owner arrives, by a push, a link or a reload, the levels above are written into history under the page first ([Back follows the page tree](docs/adr/2026-10-30-1125-back-follows-the-page-tree.md)).
55
55
  _Avoid_: nav stack, breadcrumbs
56
56
 
57
57
  **Hub page**:
58
- The hub's status page, `/_hub/`, which the sidebar's Hub row opens: a pause or Keep going banner at the **pause line**, a banner while pushes are held or snoozed, with End snooze on a snooze, then **usage readings**, then the **pending prompts** of sessions that own no board, **Health**, whose Hub row reads the **hub status** and says Keeping awake and until when while Keep awake is on, **Integrations**, then **Boards** and **Pages** with each site's health and each board's hub links and watcher, and on each board a Restart that stops its session, restarts its server and resumes the session ([0121](docs/adr/0121-a-board-restarts-from-its-row-on-the-hub-page.md)), each session's remembered Always allow rules read-only under its board, polling status, then the **hub settings** summary rows ([0050](docs/adr/0050-a-sidebar-of-every-board-replaces-the-hub-home.md), [0060](docs/adr/0060-background-sessions-prompts-come-to-the-phone.md)).
58
+ The hub's status page, `/_hub/`, which the sidebar's Hub row opens: a pause or Keep going banner at the **pause line**, a banner while pushes are held or snoozed, with End snooze on a snooze, then **usage readings**, then the **pending prompts** of sessions that own no board, **Health**, whose Hub row reads the **hub status** and says Keeping awake and until when while Keep awake is on, **Integrations**, then **Boards** and **Pages** with each site's health and each board's hub links and watcher, and on each board a Restart that stops its session, restarts its server and resumes the session ([a board restarts from its row on the Hub page](docs/adr/2026-11-02-1736-a-board-restarts-from-its-row-on-the-hub-page.md)), each session's remembered Always allow rules read-only under its board, polling status, then the **hub settings** summary rows ([a sidebar of every board replaces the hub home](docs/adr/2026-10-29-1639-a-sidebar-of-every-board-replaces-the-hub-home.md), [a background session's prompts and questions come to the phone](docs/adr/2026-10-30-1516-background-sessions-prompts-come-to-the-phone.md)).
59
59
  _Avoid_: dashboard, console, hub home
60
60
 
61
61
  **Hub status**:
62
- The word on the Hub row of the sidebar and the hub page's Health card: **Healthy** (green); **Degraded** (amber) while a board's hub link stays broken past its grace period or the hub runs older code than its files; "1 site down" (red) only while a site is down. Integrations that aren't set up don't count. On the hub page, tapping it jumps to Integrations. A board whose link fails reads "Degraded · listening" in amber, with the failing link named underneath ([0149](docs/adr/0149-the-hub-reads-healthy-degraded-or-a-site-down.md)).
62
+ The word on the Hub row of the sidebar and the hub page's Health card: **healthy** (green); **degraded** (amber) while a board's hub link stays broken past its grace period or the hub runs older code than its files; "1 site down" (red) only while a site is down. Integrations that aren't set up don't count. On the hub page, tapping it jumps to Integrations. A board whose link fails reads "degraded · listening" in amber, with the failing link named underneath ([the hub reads Healthy, Degraded or a site down, and notifications leave the board links](docs/adr/2026-11-03-0501-the-hub-reads-healthy-degraded-or-a-site-down.md)).
63
63
  _Avoid_: broken, hub health
64
64
 
65
65
  **Integration readiness**:
66
- What each integration needs before its features can run: the Hub page’s Integrations section between Health and Boards lists GitHub, Codex, Linear, Slack, Tailscale and Notifications in that order. Ready says what passed; Not ready is orange and says what is missing, how to fix it and which features wait. A board session reports whether Claude’s Slack connector is available; the hub shares the same readiness and words with feature gates ([0108](docs/adr/0108-integrations-show-readiness-and-features-wait.md)).
66
+ What each integration needs before its features can run: the Hub page’s Integrations section between Health and Boards lists GitHub, Codex, Linear, Slack, Tailscale and Notifications in that order. A row reading ready says what passed; one reading not ready is orange and says what is missing, how to fix it and which features wait. A board session reports whether Claude’s Slack connector is available; the hub shares the same readiness and words with feature gates ([integrations show readiness, and features wait until theirs is ready](docs/adr/2026-11-02-1118-integrations-show-readiness-and-features-wait.md)).
67
67
  _Avoid_: integration health, availability
68
68
 
69
69
  **Usage reading**:
70
- The last reported Claude or Codex usage for its 5-hour and weekly windows, with reset times and when read. The sidebar’s Hub row shows each tool’s 5-hour bar and the hub page shows both windows with the **pause line** tick; a reading older than its window reads “last seen” with a grey striped bar, otherwise a window whose reset passed reads as reset. Claude appears after its status line reports usage. Codex's bars show only while the **Codex setting** in effect isn't Off; the hub page keeps Codex's block either way, opening with the setting's control ([0082](docs/adr/0082-the-sidebar-shows-claude-and-codex-usage-under-hub.md), [0086](docs/adr/0086-codex-share-sits-in-the-usage-card.md), [0092](docs/adr/0092-codex-share-follows-whether-codex-is-usable.md)).
70
+ The last reported Claude or Codex usage for its 5-hour and weekly windows, with reset times and when read. The sidebar’s Hub row shows each tool’s 5-hour bar and the hub page shows both windows with the **pause line** tick; a reading older than its window reads “last seen” with a grey striped bar, otherwise a window whose reset passed reads as reset. Claude appears after its status line reports usage. Codex's bars show only while the **Codex setting** in effect isn't Off; the hub page keeps Codex's block either way, opening with the setting's control ([the sidebar shows Claude and Codex usage under Hub](docs/adr/2026-11-01-1338-the-sidebar-shows-claude-and-codex-usage-under-hub.md), [Codex share sits in the Usage card](docs/adr/2026-11-01-1428-codex-share-sits-in-the-usage-card.md), [Codex share follows whether Codex is usable](docs/adr/2026-11-01-1521-codex-share-follows-whether-codex-is-usable.md)).
71
71
  _Avoid_: quota, live usage
72
72
 
73
73
  **Pause line**:
74
- The Usage card's “Pause work at”, last in the group below Codex: `pauseAt` in `~/.claude/kickflip/settings.json`, 50–100 in steps of 5, default 90 (10% buffer); 100 reads Off. Either live Claude window at or over it pauses new work until that window resets. Running steps finish; builders and new agents wait, watchers hold the hub's work events, and owner messages get a brief “paused until <time>”. Keep going lifts that window's pause until its reset; Stop restores it. Codex hands work to Opus builders at the same line, without pausing. The Hub banner and sidebar and board header status slots show the pause, never the logo. `shared/usage-gate.mjs` owns it; `kickflip usage-gate` prints it ([0094](docs/adr/0094-work-pauses-at-the-pause-line.md)).
74
+ The Usage card's “Pause work at”, last in the group below Codex: `pauseAt` in `~/.claude/kickflip/settings.json`, 50–100 in steps of 5, default 90 (10% buffer); 100 reads Off. Either live Claude window at or over it pauses new work until that window resets. Running steps finish; builders and new agents wait, watchers hold the hub's work events, and owner messages get a brief “paused until <time>”. Keep going lifts that window's pause until its reset; Stop restores it. Codex hands work to Opus builders at the same line, without pausing. The Hub banner and sidebar and board header status slots show the pause, never the logo. `shared/usage-gate.mjs` owns it; `kickflip usage-gate` prints it ([work pauses at the pause line](docs/adr/2026-11-01-1710-work-pauses-at-the-pause-line.md)).
75
75
  _Avoid_: buffer threshold, quota guard
76
76
 
77
77
  **Claude model**:
78
- The Usage card's Opus · Auto · Sonnet control, opening Claude's block: `claudeModel` in `~/.claude/kickflip/settings.json`, default Auto. It decides which model builds a card Claude builds: Opus or Sonnet always, or under Auto the card's own `--model`, else Sonnet for a card `--size small` and Opus for the rest. `builder pick` prints it with why, and a build's `builder start` refuses a `--model` it rules out. Codex builds, prototypes and grills don't read it ([0162](docs/adr/0162-usage-picks-opus-auto-or-sonnet-for-claude-builders.md)).
78
+ The Usage card's Opus · Auto · Sonnet control, opening Claude's block: `claudeModel` in `~/.claude/kickflip/settings.json`, default Auto. It decides which model builds a card Claude builds: Opus or Sonnet always, or under Auto the card's own `--model`, else Sonnet for a card `--size small` and Opus for the rest. `builder pick` prints it with why, and a build's `builder start` refuses a `--model` it rules out. Codex builds, prototypes and grills don't read it ([usage picks Opus, Auto or Sonnet for Claude builders, and builder pick says which and why](docs/adr/2026-11-03-1526-usage-picks-opus-auto-or-sonnet-for-claude-builders.md)).
79
79
  _Avoid_: Opus builders, allow Opus
80
80
 
81
81
  **Board registry**:
82
- `hub/boards.mjs`, the only hub code that reads a board's `board.json` and wave files. Every hub feature that serves boards (the GitHub check, wakes, rules, the handshake, the not-listening push) takes its boards from it, so a board over the waves and a board over its own file get the same links ([0040](docs/adr/0040-one-board-registry-for-every-hub-feature.md)).
82
+ `hub/boards.mjs`, the only hub code that reads a board's `board.json` and wave files. Every hub feature that serves boards (the GitHub check, wakes, rules, the handshake, the not-listening push) takes its boards from it, so a board over the waves and a board over its own file get the same links ([one board registry for every hub feature](docs/adr/2026-10-29-1639-one-board-registry-for-every-hub-feature.md)).
83
83
  _Avoid_: board list, wave boards and file boards (as separate code paths)
84
84
 
85
85
  **Site**:
@@ -87,7 +87,7 @@ A route on the hub (`/<route>`) served by one owning Claude session, or by none
87
87
  _Avoid_: app, page (a site has several pages)
88
88
 
89
89
  **Plain page**:
90
- A site joined with `kickflip join --name "<name>"` and `--port` (a server its session runs, which reads Down while nothing answers) or `--dir` (files the hub serves itself), without `--session`. It has no owning session, events, watcher or Needs you badge, and shows under Pages like any site that isn't a board. `--watch --session <id>` joins a site with all of those ([0087](docs/adr/0087-a-page-joins-without-a-session.md)). Every join's `--name` gives the site's title and route, the name hyphenated ([0143](docs/adr/0143-kickflip-join-adds-the-current-repository-as-a-board.md)).
90
+ A site joined with `kickflip join --name "<name>"` and `--port` (a server its session runs, which reads Down while nothing answers) or `--dir` (files the hub serves itself), without `--session`. It has no owning session, events, watcher or Needs you badge, and shows under Pages like any site that isn't a board. `--watch --session <id>` joins a site with all of those ([a page joins without a session](docs/adr/2026-11-01-1446-a-page-joins-without-a-session.md)). Every join's `--name` gives the site's title and route, the name hyphenated ([kickflip join adds the current repository as a board](docs/adr/2026-11-03-0248-kickflip-join-adds-the-current-repository-as-a-board.md)).
91
91
  _Avoid_: minimal site, unwatched site
92
92
 
93
93
  **Owner**:
@@ -99,45 +99,57 @@ A board's owning session as the manifest records it in the site's owner: its id,
99
99
  _Avoid_: orchestrator process, agent
100
100
 
101
101
  **Hub session**:
102
- The owning session of the **hub board**, the one board whose manifest entry has `hub: true` (`kickflip set <route> --hub`, `kickflip join --hub`). It is the one board session that runs in the foreground, inside the tmux session `kickflip-<route>` the hub starts, which `kickflip hub` attaches the owner's terminal to; it gets the phone permission hook like a background session. Nothing else sets the hub board apart: it works on its own folder as a **local board**, closes and restarts like any board. Code finds it by the flag, never by its route. A hub board is optional, and no feature depends on its session ([0147](docs/adr/0147-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
102
+ The owning session of the **hub board**, the one board whose manifest entry has `hub: true` (`kickflip set <route> --hub`, `kickflip join --hub`). It is the one board session that runs in the foreground, inside the tmux session `kickflip-<route>` the hub starts, which `kickflip hub` attaches the owner's terminal to; it gets the phone permission hook like a background session. Nothing else sets the hub board apart: it works on its own folder as a **local board**, closes and restarts like any board. Code finds it by the flag, never by its route. A hub board is optional, and no feature depends on its session ([boards run in the background, sleep and wake from the page, and the hub board runs in tmux](docs/adr/2026-11-03-0313-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
103
103
  _Avoid_: hub server, permanent orchestrator
104
104
 
105
105
  **Live**:
106
106
  A session whose `~/.claude/sessions/<pid>.json` record names it and whose process still runs, started when the record says. A live session is never started or resumed again.
107
107
 
108
108
  **Listening**:
109
- A board is listening while its owner session is live and a watcher runs for it. A watcher outlives its session, so a watcher alone isn't listening. A board that isn't listening is waking, **asleep** or deaf. The board header, the sidebar, the events link and the not-listening push read that state, and the **session wake** uses this test ([0061](docs/adr/0061-a-boards-session-wakes-when-an-event-arrives.md)).
109
+ A board is listening while its owner session is live and a watcher runs for it. A watcher outlives its session, so a watcher alone isn't listening. A board that isn't listening is waking, **asleep** or not listening. The board header, the sidebar, the events link and the not-listening push read that state, and the **session wake** uses this test ([a board's session wakes when an event arrives, and live means its session runs](docs/adr/2026-10-30-1601-a-boards-session-wakes-when-an-event-arrives.md)).
110
110
 
111
111
  **Asleep**:
112
- A board whose owner session isn't live but that the hub can wake on its next event or a tap on its page: a session and folder are recorded, and no **session wake** of this outage has failed or gone unanswered. It reads asleep in grey in the sidebar and the board header, its events link passes, and it gets no not-listening push. Once the hub resumed its session it is waking, and reads waking… in grey until it listens. A board that is neither listening, waking nor asleep is deaf and reads not listening in red ([0061](docs/adr/0061-a-boards-session-wakes-when-an-event-arrives.md), [0147](docs/adr/0147-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
112
+ A board whose owner session isn't live but that the hub can wake on its next event or a tap on its page: a session and folder are recorded, and no **session wake** of this outage has failed or gone unanswered. It reads asleep in grey in the sidebar and the board header, its events link passes, and it gets no not-listening push. Once the hub resumed its session it is waking, and reads waking… in grey until it listens. A board that is neither listening, waking nor asleep is **not listening** and reads so in red ([a board's session wakes when an event arrives, and live means its session runs](docs/adr/2026-10-30-1601-a-boards-session-wakes-when-an-event-arrives.md), [boards run in the background, sleep and wake from the page, and the hub board runs in tmux](docs/adr/2026-11-03-0313-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
113
113
  _Avoid_: idle, stopped, offline
114
114
 
115
+ **Not listening**:
116
+ A board that isn't listening, waking nor **asleep**: its session or watcher isn't running and the hub can't wake it, so events wait. It reads not listening in red in the board header, the sidebar and the hub page, "Not listening: …" in its events link and "X isn't listening" in its push ([status words are lowercase, and a board nothing will wake reads not listening](docs/adr/2026-11-03-1822-status-words-are-lowercase.md)).
117
+ _Avoid_: deaf, stopped, not responding
118
+
119
+ **Status word**:
120
+ A word in a status slot: beside a status dot, in a hub page row's status, in the board header's time slot, in a running or failed build chip, or as a usage block's tag. It is lowercase (down, starting, working, implementing, paused, healthy, degraded, up, not listening…), while sentences, toasts, tooltips, pushes, titles and button labels keep their capital ([status words are lowercase, and a board nothing will wake reads not listening](docs/adr/2026-11-03-1822-status-words-are-lowercase.md)).
121
+ _Avoid_: status label, badge text
122
+
115
123
  **Session wake**:
116
- The hub resuming a board session as soon as an event lands while that session isn't live, or the owner taps the board's page while it is **asleep** (the header's refresh or any other tap or send, through `/_hub/wake`), or, as a fallback, once its board hasn't been listening for 3 minutes with an event its session hasn't heard. Once per outage, then one push to the owner if the board still isn't listening 5 minutes later. A session that idles out with nothing waiting stays stopped. The hub board's session comes back in its tmux session ([0061](docs/adr/0061-a-boards-session-wakes-when-an-event-arrives.md), [0147](docs/adr/0147-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
124
+ The hub resuming a board session as soon as an event lands while that session isn't live, or the owner taps the board's page while it is **asleep** (the header's refresh or any other tap or send, through `/_hub/wake`), or, as a fallback, once its board hasn't been listening for 3 minutes with an event its session hasn't heard. Once per outage, then one push to the owner if the board still isn't listening 5 minutes later. A session that idles out with nothing waiting stays stopped. The hub board's session comes back in its tmux session ([a board's session wakes when an event arrives, and live means its session runs](docs/adr/2026-10-30-1601-a-boards-session-wakes-when-an-event-arrives.md), [boards run in the background, sleep and wake from the page, and the hub board runs in tmux](docs/adr/2026-11-03-0313-boards-run-in-the-background-and-the-hub-board-in-tmux.md)).
117
125
  _Avoid_: auto-resume, respawn, wake (a daily wake is the morning `check-github`)
118
126
 
119
127
  **Push**:
120
- A notification from the hub, on the phone or a desktop browser, that opens a page. Each push has a kind, and `hub/push.mjs` `deliver()` refuses any other: `action` when a card's **Action needed** appears or changes, `prompt` for a **pending prompt**, `fault` for what only the owner can fix (a board not listening, a session that didn't come back, an urgent production problem) ([0006](docs/adr/0006-pushes-only-when-something-waits-on-the-owner.md)). Answers, merges, Stale and other news never push; the threads' unread marks and the board carry them. The board server sends each action push itself, under the card's tag or `topic-<id>` for a Needs you topic, when Action needed appears, changes kind or gains a question ([0133](docs/adr/0133-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)). Questions, steps and prototypes go at once; drafts on Ready and Merge go when their tick ends, and one under a card's tag replaces the last and alerts again ([0030](docs/adr/0030-pushes-go-by-kind-and-each-arrives-on-its-own.md)). When the queue goes out, a board with one queued push gets it as it is, and a board with several gets one summary of what waits on its Needs you then, tagged `summary:<route>` so the newest replaces the last, or nothing when nothing waits ([0120](docs/adr/0120-queued-pushes-go-as-one-summary-per-board.md)). Replies don't push; a push that goes out anyway says how many came since the last one. With notifications off every push is dropped; a snooze and Off on weekends hold pushes until they end, and urgent ones go through those holds ([0032](docs/adr/0032-notifications-can-be-off-snoozed-or-off-on-weekends.md)). While the owner is **at the host**, an action push goes to the host only ([0065](docs/adr/0065-pushes-go-to-the-mac-only-while-the-owner-is-at-it.md)).
128
+ A notification from the hub, on the phone or a desktop browser, that opens a page. Each push has a kind, and `hub/push.mjs` `deliver()` refuses any other: `action` when a card's **Action needed** appears or changes, `prompt` for a **pending prompt**, `fault` for what only the owner can fix (a board not listening, a session that didn't come back, an urgent production problem) ([a push goes out only when something waits on the owner, on the hub's schedule](docs/adr/2026-10-29-1639-pushes-only-when-something-waits-on-the-owner.md)). Answers, merges, Stale and other news never push; the threads' unread marks and the board carry them. The board server sends each action push itself, under the card's tag or `topic-<id>` for a Needs you topic, when Action needed appears, changes kind or gains a question ([the board records what it knows, and commands make the rule calls](docs/adr/2026-11-03-0003-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)). Questions, steps and prototypes go at once; drafts on Ready and Merge go when their tick ends, and one under a card's tag replaces the last and alerts again ([pushes go out by kind, and each arrives on its own](docs/adr/2026-10-29-1639-pushes-go-by-kind-and-each-arrives-on-its-own.md)). When the queue goes out, a board with one queued push gets it as it is, and a board with several gets one summary of what waits on its Needs you then, tagged `summary:<route>` so the newest replaces the last, or nothing when nothing waits ([queued pushes go as one summary per board](docs/adr/2026-11-02-1733-queued-pushes-go-as-one-summary-per-board.md)). Replies don't push; a push that goes out anyway says how many came since the last one. With notifications off every push is dropped; a snooze and Off on weekends hold pushes until they end, and urgent ones go through those holds ([notifications can be off, snoozed, or off on weekends](docs/adr/2026-10-29-1639-notifications-can-be-off-snoozed-or-off-on-weekends.md)). While the owner is **at the host**, an action push goes to the host only ([pushes go to the Mac only while the owner is at it](docs/adr/2026-10-30-1704-pushes-go-to-the-mac-only-while-the-owner-is-at-it.md)).
121
129
  _Avoid_: alert, notification (for the act of sending)
122
130
 
123
131
  **At the host**:
124
- The owner's presence that keeps pushes off the phone: the host's screen is unlocked and a key or the pointer was used in the last 3 minutes, whatever app is in front (`hub/presence.mjs`). It is read from macOS `ioreg`, so on a Linux host the owner always reads away. Then an action push goes only to the desktop subscriptions, and the phone never gets it later; prompts, faults and urgent pushes still reach the phone, and with no desktop subscription every push does. Otherwise the owner is away and every push goes to every device ([0065](docs/adr/0065-pushes-go-to-the-mac-only-while-the-owner-is-at-it.md)).
132
+ The owner's presence that keeps pushes off the phone: the host's screen is unlocked and a key or the pointer was used in the last 3 minutes, whatever app is in front (`hub/presence.mjs`). It is read from macOS `ioreg`, so on a Linux host the owner always reads away. Then an action push goes only to the desktop subscriptions, and the phone never gets it later; prompts, faults and urgent pushes still reach the phone, and with no desktop subscription every push does. Otherwise the owner is away and every push goes to every device ([pushes go to the Mac only while the owner is at it](docs/adr/2026-10-30-1704-pushes-go-to-the-mac-only-while-the-owner-is-at-it.md)).
125
133
  _Avoid_: at the Mac, active, online, desktop app active
126
134
 
127
- **Polling interval**:
128
- The hub's one schedule, a list of windows with their minutes: on each slot it checks GitHub, wakes a board's owning session with `github-change` when a PR on its cards changed, pushes once for each board that isn't listening, then sends the queued pushes. At each daily wake time it also sends each board one `check-github {reason: "morning"}`, changed or not. With hold pushes overnight on, pushes queued in the last window wait for the first window's start ([0025](docs/adr/0025-the-hub-polls-github-and-sends-pushes-on-one-interval.md)).
129
- _Avoid_: push schedule, send-at-once hours, cron
135
+ **Check cadence**:
136
+ How often the hub checks: every minute while the owner is present (the Mac in use, or a board page tapped on any device) and every 5 while away, or every 5 and 15 while GitHub has under 1,000 points left. Coming back checks at once. Each check fetches and pulls every board's repo and reads every card PR in one GraphQL query, wakes a board's owning session with `github-change` when a PR on its cards changed, pushes once for each board that isn't listening, then sends the queued pushes. While away, a moon sits right of the board title ([the hub checks every minute while you’re here and every 5 when away](docs/adr/2026-11-04-0226-the-hub-checks-every-minute-while-youre-here-and-every-5-when-away.md)).
137
+ _Avoid_: polling interval, polling window, push schedule, cron
138
+
139
+ **Quiet hours**:
140
+ A start and end time, 10:00pm to 8:00am by default. With its hold on, pushes queued inside it wait for its end. Snooze tonight ends at its start, morning at its end and monday at Monday's end; Off on weekends runs from Friday's start to Monday's end. At its end the hub sends each board one `check-github {reason: "morning"}`, the daily wake ([the hub checks every minute while you’re here and every 5 when away](docs/adr/2026-11-04-0226-the-hub-checks-every-minute-while-youre-here-and-every-5-when-away.md)).
141
+ _Avoid_: overnight window, wake times
130
142
 
131
143
  **Hub settings**:
132
- The six summary rows below the **hub page**’s health and status: Notifications, Polling, Keep awake, Linear, Rules for every board and Closed boards. Each opens its controls in a centred modal with its own scroll area, including Polling’s schedule editor. Snooze and Keep awake share one duration picker: 1h, 3h, 6h, 1d, Forever and Custom. Keep awake has the hub run `caffeinate -ims` until its end, and is disabled on hosts other than macOS ([0112](docs/adr/0112-snooze-and-keep-awake-share-one-duration-picker.md)). Old Hub Settings links open the matching modal over Hub ([0075](docs/adr/0075-hub-settings-open-as-modals.md)).
144
+ The six summary rows below the **hub page**’s health and status: Notifications, Quiet hours, Keep awake, Linear, Rules for every board and Closed boards. Each opens its controls in a centred modal with its own scroll area. Snooze and Keep awake share one duration picker: 1h, 3h, 6h, 1d, Forever and Custom. Keep awake has the hub run `caffeinate -ims` until its end, and is disabled on hosts other than macOS ([snooze and Keep awake share one duration picker](docs/adr/2026-11-02-1402-snooze-and-keep-awake-share-one-duration-picker.md)). Old Hub Settings links open the matching modal over Hub ([hub settings open as modals](docs/adr/2026-11-01-1221-hub-settings-open-as-modals.md)).
133
145
  _Avoid_: Hub Settings page, preferences, hub config
134
146
 
135
147
  **Board Settings**:
136
- The centred modal opened from a board header’s gear, at every width, which scrolls inside on a phone. It contains only that board’s settings: repo and branch (Change uses the same list and GitHub link search as New board), ticket source, auto-merge, auto-build, auto-pull, auto-triage, reviewers, rules and Close board with typed-name confirmation. Closing returns to the same board and open card without another history entry ([0074](docs/adr/0074-hub-settings-expand-in-place-and-board-settings-open-in-a-modal.md)).
148
+ The centred modal opened from a board header’s gear, at every width, which scrolls inside on a phone. It contains only that board’s settings: repo and branch (Change uses the same list and GitHub link search as New board), ticket source, auto-merge, auto-build, auto-pull (Auto implement Todo cards) with Maximum parallel implementers, auto-triage, reviewers, rules and Close board with typed-name confirmation. Closing returns to the same board and open card without another history entry ([hub settings expand in place and board settings open in a modal](docs/adr/2026-10-31-1721-hub-settings-expand-in-place-and-board-settings-open-in-a-modal.md)).
137
149
  _Avoid_: Settings page
138
150
 
139
151
  **Codex setting**:
140
- The one choice for every board, made in Codex’s block of the hub page’s Usage card ([0086](docs/adr/0086-codex-share-sits-in-the-usage-card.md)): Auto and Always on have Codex build and review, with Opus builders taking over while Codex is past the **pause line** until it resets; out of usage, Auto keeps Opus builders on and Always on pauses that work until a usage-reset check succeeds; Off means Opus builds and reviews. Unset means Auto. While Codex isn't usable, installed and logged in, the setting in effect is Off whatever is stored, and the control is greyed out; running out of usage doesn't make Codex unusable ([0092](docs/adr/0092-codex-share-follows-whether-codex-is-usable.md)). No session overrides it ([0105](docs/adr/0105-the-hubs-codex-share-is-the-only-codex-setting.md)).
152
+ The one choice for every board, made in Codex’s block of the hub page’s Usage card ([Codex share sits in the Usage card](docs/adr/2026-11-01-1428-codex-share-sits-in-the-usage-card.md)): Auto and Always on have Codex build and review, with Opus builders taking over while Codex is past the **pause line** until it resets; out of usage, Auto keeps Opus builders on and Always on pauses that work until a usage-reset check succeeds; Off means Opus builds and reviews. Unset means Auto. While Codex isn't usable, installed and logged in, the setting in effect is Off whatever is stored, and the control is greyed out; running out of usage doesn't make Codex unusable ([Codex share follows whether Codex is usable](docs/adr/2026-11-01-1521-codex-share-follows-whether-codex-is-usable.md)). No session overrides it ([the hub's Codex share is the only Codex setting](docs/adr/2026-11-01-2355-the-hubs-codex-share-is-the-only-codex-setting.md)).
141
153
  _Avoid_: Codex rule, board Codex toggle
142
154
 
143
155
  **Waiting count**:
@@ -145,7 +157,7 @@ The badge on a site's row in the sidebar: how many things the site's `GET /_clau
145
157
  _Avoid_: unread count, inbox
146
158
 
147
159
  **Status word**:
148
- The coloured word that leads a site's sub line in the sidebar when something urgent holds, most urgent first: Paused while the **pause line** holds, otherwise Down, not listening (a board that is neither **listening**, waking nor **asleep**), Starting, Stopped (muted), "N need you", Working, waking… (muted), asleep (muted) or Building. Lane chips with the site's open-card counts follow it; a calm site shows only the chips ([0037](docs/adr/0037-the-hub-home-shows-status-not-descriptions.md), [0077](docs/adr/0077-need-you-outranks-working.md)).
160
+ The coloured word that leads a site's sub line in the sidebar when something urgent holds, most urgent first: Paused while the **pause line** holds, otherwise Down, not listening (a board that is neither **listening**, waking nor **asleep**), Starting, Stopped (muted), "N need you", Working, waking… (muted), asleep (muted) or Building. Lane chips with the site's open-card counts follow it; a calm site shows only the chips ([the hub home shows status, not descriptions](docs/adr/2026-10-29-1639-the-hub-home-shows-status-not-descriptions.md), ["N need you" outranks Working](docs/adr/2026-11-01-1252-need-you-outranks-working.md)).
149
161
  _Avoid_: activity line, subtitle
150
162
 
151
163
  ### Boards
@@ -155,19 +167,19 @@ A site built from the board template that shows one or more waves as cards in la
155
167
  _Avoid_: dashboard, kanban
156
168
 
157
169
  **Closed board**:
158
- A board whose session and server have stopped and whose sidebar row is gone, with its folder, cards, threads and notes kept on the host. The hub page lists it under Closed boards; Reopen restores it and resumes its recorded session. Open PRs stay on GitHub, and running builder records end with a note ([0072](docs/adr/0072-a-closed-board-keeps-its-folder-and-can-be-reopened.md)).
170
+ A board whose session and server have stopped and whose sidebar row is gone, with its folder, cards, threads and notes kept on the host. The hub page lists it under Closed boards; Reopen restores it and resumes its recorded session. Open PRs stay on GitHub, and running builder records end with a note ([a closed board keeps its folder and can be reopened](docs/adr/2026-10-31-1603-a-closed-board-keeps-its-folder-and-can-be-reopened.md)).
159
171
  _Avoid_: deleted board, archived board
160
172
 
161
173
  **Hub links**:
162
- What the hub owes a board, each passing or broken: GitHub polling (not on a board on a plain git remote), the repo fetch (on a board with a repo, the hub's last `git fetch` of it worked; when it failed, git's error line and the fix, such as `gh auth setup-git`, or `git ls-remote <link>` on a plain git remote), events (the board is **listening**), daily wakes and reviewer links; whether a device gets pushes is the Notifications integration, not a hub link ([0149](docs/adr/0149-the-hub-reads-healthy-degraded-or-a-site-down.md)). The hub link (the hub runs the code in its files) is the hub's own, shown in amber only on the sidebar's Hub row and the hub page's Health card ([0064](docs/adr/0064-every-builder-works-in-a-worktree.md)). The In Review header's GitHub mark, or on a plain git remote the branch mark beside its host/path, opens them as a sheet, red-dotted only while one stays broken past its grace period; until then it is **settling** ([0046](docs/adr/0046-hub-links-turn-red-only-after-a-grace-period.md)). A new board tests them with a **handshake**: a `hello` event the session's watcher answers itself, with a Connecting checklist on the board until the watcher answered and GitHub checks reach it, the GitHub step left out on a plain git remote ([0040](docs/adr/0040-one-board-registry-for-every-hub-feature.md)).
174
+ What the hub owes a board, each passing or broken: GitHub polling (not on a board on a plain git remote), the repo fetch (on a board with a repo, the hub's last `git fetch` of it worked; when it failed, git's error line and the fix, such as `gh auth setup-git`, or `git ls-remote <link>` on a plain git remote), events (the board is **listening**), daily wakes and reviewer links; whether a device gets pushes is the Notifications integration, not a hub link ([the hub reads Healthy, Degraded or a site down, and notifications leave the board links](docs/adr/2026-11-03-0501-the-hub-reads-healthy-degraded-or-a-site-down.md)). The hub link (the hub runs the code in its files) is the hub's own, shown in amber only on the sidebar's Hub row and the hub page's Health card ([every builder works in a worktree, and the hub's own fault shows once](docs/adr/2026-10-30-1654-every-builder-works-in-a-worktree.md)). The In Review header's GitHub mark, or on a plain git remote the branch mark beside its host/path, opens them as a sheet, red-dotted only while one stays broken past its grace period; until then it is **settling** ([hub links turn red only after a grace period](docs/adr/2026-10-29-1639-hub-links-turn-red-only-after-a-grace-period.md)). A new board tests them with a **handshake**: a `hello` event the session's watcher answers itself, with a Connecting checklist on the board until the watcher answered and GitHub checks reach it, the GitHub step left out on a plain git remote ([one board registry for every hub feature](docs/adr/2026-10-29-1639-one-board-registry-for-every-hub-feature.md)).
163
175
  _Avoid_: health, status, integrations
164
176
 
165
177
  **Change signal**:
166
- The board server's note on its `api/stream` that a file the board reads changed; the hub passes it on as `change {route}` on its one stream, and an open board reloads at once. The header's time counts from the last one that brought something new, or the last ↻ tap ([0031](docs/adr/0031-the-board-reloads-on-a-change-signal.md)).
178
+ The board server's note on its `api/stream` that a file the board reads changed; the hub passes it on as `change {route}` on its one stream, and an open board reloads at once, naming the version it shows, so a changed board comes as a patch of the cards, questions and topics that changed ([the board sends per-card patches](docs/adr/2026-11-04-0332-the-board-sends-per-card-patches.md)). The header's time counts from the last one that brought something new, or the last ↻ tap ([the board reloads on a change signal](docs/adr/2026-10-29-1639-the-board-reloads-on-a-change-signal.md)).
167
179
  _Avoid_: push (a push is a notification from the hub), live update
168
180
 
169
181
  **Owner tap**:
170
- A button the owner taps on the board, sent as an event. The board's rule for taps: one whose result follows from the tap alone (a bump, Hold, Done, Build, an edit) is applied by the board server inside the POST, which answers with the board, and the page draws it at once, a bump, unbump, edit or delete even before the POST, taken back off with a toast if the POST fails. The event is a record for the session, never what the owner waits on; only judgment or outside tools (Grill, prototypes, a nudge, triage, a GitHub check) wait on the session. A tap reloads the board once, through the change signal ([0151](docs/adr/0151-every-owner-tap-the-server-can-apply-draws-at-once.md)).
182
+ A button the owner taps on the board, sent as an event. The board's rule for taps: one whose result follows from the tap alone (a bump, Hold, Done, Build, an edit) is applied by the board server inside the POST, which answers with the board, and the page draws it at once, a bump, unbump, edit or delete even before the POST, taken back off with a toast if the POST fails. The event is a record for the session, never what the owner waits on; only judgment or outside tools (Grill, prototypes, a nudge, triage, a GitHub check) wait on the session. A tap reloads the board once, through the change signal ([every owner tap the server can apply draws at once](docs/adr/2026-11-03-0500-every-owner-tap-the-server-can-apply-draws-at-once.md)).
171
183
  _Avoid_: action, click
172
184
 
173
185
  **Wave**:
@@ -175,43 +187,47 @@ A set of work items built and reviewed together, with its reviewers.
175
187
  _Avoid_: batch, sprint, epic
176
188
 
177
189
  **Lineup**:
178
- What the owner calls a wave on a board: a named set of cards from one wave file, in build order, with a goal and a short note. Only the owner asks for one, with the +, or Claude proposes one as a board question when it spots a grouping in Todo. `board.mjs lineup create` makes each card blocked by the one before it and writes the note to `lineup-<slug>.md` beside the wave file; each card stays one PR and starts on its own as it unblocks. Its cards carry a grey chip with its name, in the row under their other chips. It is open until `lineup finish` or until all its cards are Done ([0109](docs/adr/0109-a-wave-the-owner-asks-for-is-a-lineup-of-cards.md)).
190
+ What the owner calls a wave on a board: a named set of cards from one wave file, in **wave phases** in build order, with a goal and a short note. Only the owner asks for one, with the +, or Claude proposes one as a board question when it spots a grouping in Todo. `board.mjs lineup create --phase <keys> --phase …` makes each card blocked by every card of the phase before and writes the note to `lineup-<slug>.md` beside the wave file; each card stays one PR and starts on its own as it unblocks, so one phase's cards build side by side ([a wave builds in phases, and cards in one phase build side by side](docs/adr/2026-11-04-0238-a-wave-builds-in-phases.md)). A lineup made before phases is a chain, one card per phase. Todo shows it as a **wave band**. It is open until `lineup finish` or until all its cards are Done ([a wave the owner asks for is a lineup of cards](docs/adr/2026-11-02-1202-a-wave-the-owner-asks-for-is-a-lineup-of-cards.md)).
179
191
  _Avoid_: wave (in code and `board.mjs`, where a wave is a wave file), group, epic
180
192
 
181
- **Waves section**:
182
- The lane above In Review with one row per open **lineup**, then on a board over `~/.claude/waves` one per unfinished wave file: its name and "N of M merged", and for a lineup its Goal and Order lines and "Notes ↗ · Triage", while a wave file has Triage at the end of its name line. Notes opens the goal, order and note through `notes.html?wave=<slug>`. Tapping a row shows only its cards in the lanes, under "Showing <name> only · Show all" ([0109](docs/adr/0109-a-wave-the-owner-asks-for-is-a-lineup-of-cards.md)).
183
- _Avoid_: wave bars, wave filter, pills
193
+ **Wave phase**:
194
+ One step of a **lineup**: a set of its cards that build side by side, each blocked by every card of the phase before. Wave triage groups cards into phases by the files and areas they touch, and two cards in one phase that touch the same file rebase at land as any card does. A wave band numbers its cards by phase ([a wave builds in phases, and cards in one phase build side by side](docs/adr/2026-11-04-0238-a-wave-builds-in-phases.md)).
195
+ _Avoid_: stage, batch; a builder's phase (reading, building, …) is its progress, not this
196
+
197
+ **Wave band**:
198
+ A wave shown inside Todo: one band per open **lineup**, then on a board over `~/.claude/waves` one per unfinished wave file, above Todo's cards in no wave ("Not in a wave"). Its head reads its name (the goal as its tooltip, or a long-press popover), its Todo count, "N of M merged" and its started cards, then "Notes ↗ · Triage" (a wave file has only Triage), then Implement for a lineup's next card when it is ready, else "next: #N <why not>". Open, it lists its Todo cards in wave order with step numbers, one per phase, and a ⋯ menu that swaps a card with the Todo card above or below, each taking the other's phase, after one "N done" line. A lineup's next card is its first ready Todo card, so a phase's ready cards take Implement in turn. Only the first band with a ready next card starts open ([waves are bands in Todo, each with its next card's Implement](docs/adr/2026-11-03-1840-waves-are-bands-in-todo.md)).
199
+ _Avoid_: Waves section, wave bars, wave filter, pills
184
200
 
185
201
  **Wave triage**:
186
- Claude reading the code for a lineup's unstarted cards and proposing to split, merge, add or close cards, as one open board question per change on topic `lineup:<slug>`, which Needs you shows as "<wave> · N questions". For a wave file, Claude checks each unfinished card's PR, CI, reviews and blockers, and whether a merged card already covers a Todo card, fixes what it can, and asks one question per card that needs the owner on topic `wave:<slug>`. The row's Triage confirms, sends `wave-triage {lineup}` or `wave-triage {wave}` and reads Triaging… in orange until the session replies to that event, then "Triage: N open questions" in grey while any is open or answered ([0109](docs/adr/0109-a-wave-the-owner-asks-for-is-a-lineup-of-cards.md)).
202
+ Claude reading the code for a lineup's unstarted cards and proposing to split, merge, add or close cards, or to re-phase it by the files and areas its cards touch, as one open board question per change on topic `lineup:<slug>`, which Needs you shows as "<wave> · N questions". For a wave file, Claude checks each unfinished card's PR, CI, reviews and blockers, and whether a merged card already covers a Todo card, fixes what it can, and asks one question per card that needs the owner on topic `wave:<slug>`. A band's Triage confirms, sends `wave-triage {lineup}` or `wave-triage {wave}` and reads Triaging… in orange until the session replies to that event, then "Triage: N open questions" in grey while any is open or answered ([a wave the owner asks for is a lineup of cards](docs/adr/2026-11-02-1202-a-wave-the-owner-asks-for-is-a-lineup-of-cards.md)).
187
203
  _Avoid_: grooming, refinement
188
204
 
189
205
  **Architecture review**:
190
- Claude reviewing a board's repo, chosen by `hub/board-repo.mjs` `boardRepo`, with the mattpocock skills: the bulb between the board header's ↻ and gear opens a sheet with the last review and Run, which confirms. The board server makes a **lineup** "Architecture <date>", or on a board over `~/.claude/waves` a wave file of its own, whose first card is its audit card, and wakes the session with `arch-review`. The bulb glows orange while the audit card is open with no question yet. The audit card's Notes are the report, and it asks one question per finding, with possible solutions and Skip; each finding not skipped becomes a card after it. One review is open at a time, so Run while one is open opens its audit card. A board on the running kickflip clone, as the hub board is, has its review cover kickflip's code, the board template and the model, reading the live data only for its shapes. It waits, saying why, while a skill it follows isn't installed ([0125](docs/adr/0125-the-bulb-runs-an-architecture-review-of-the-boards-repo.md)).
206
+ Claude reviewing a board's repo, chosen by `hub/board-repo.mjs` `boardRepo`, with the mattpocock skills: the bulb between the board header's ↻ and gear opens a sheet with the last review and Run, which confirms. The board server makes a **lineup** "Architecture <date>", or on a board over `~/.claude/waves` a wave file of its own, whose first card is its audit card, and wakes the session with `arch-review`. The bulb glows orange while the audit card is open with no question yet. The audit card's Notes are the report, and it asks one question per finding, with possible solutions and Skip; each finding not skipped becomes a card after it. One review is open at a time, so Run while one is open opens its audit card. A board on the running kickflip clone, as the hub board is, has its review cover kickflip's code, the board template and the model, reading the live data only for its shapes. It waits, saying why, while a skill it follows isn't installed ([the bulb runs an architecture review of the board's repo](docs/adr/2026-11-02-1813-the-bulb-runs-an-architecture-review-of-the-boards-repo.md)).
191
207
  _Avoid_: improvements round, audit (for the whole review), bulb round
192
208
 
193
209
  **Reviewers**:
194
- The people who get a board's PR links once they are ready, and the weekday digest. Each board keeps its own in `board.json`, which its Settings modal lists, and a new wave copies them into its own `reviewers`. Kickflip owns the sent links in each item's `review_link_ts: {<name>: {ts, channel, reactions?}}`; one reader supplies the card, Stale age, hub Slack link and digest, with slack-bridge topic files only as a fallback. The session sends through Claude's Slack connector and records with `board.mjs review sent`, `review react` and `review digest sent`. Hub Slack identity lives in `~/.claude/kickflip/slack.json`, read or set by `board.mjs slack`; its timezone sets the weekday 09:00 digest date ([0104](docs/adr/0104-kickflip-owns-the-reviewer-record.md)).
210
+ The people who get a board's PR links once they are ready, and the weekday digest. Each board keeps its own in `board.json`, which its Settings modal lists, and a new wave copies them into its own `reviewers`. A remove there is written by the board server; an add waits on the session, which finds the person's Slack and GitHub ids ([the board server removes reviewers itself](docs/adr/2026-11-04-0119-the-board-server-removes-reviewers-itself.md)). Kickflip owns the sent links in each item's `review_link_ts: {<name>: {ts, channel, reactions?}}`; one reader supplies the card, Stale age, hub Slack link and digest, with slack-bridge topic files only as a fallback. The session sends through Claude's Slack connector and records with `board.mjs review sent`, `review react` and `review digest sent`. Hub Slack identity lives in `~/.claude/kickflip/slack.json`, read or set by `board.mjs slack`; its timezone sets the weekday 09:00 digest date ([kickflip owns the reviewer record](docs/adr/2026-11-01-2347-kickflip-owns-the-reviewer-record.md)).
195
211
  _Avoid_: approvers, watchers
196
212
 
197
213
  **Finished wave**:
198
- A wave with work items that are all merged, done or dropped. Done shows it as one row that opens to its cards, and it leaves the **Waves section** ([ADR 0012](docs/adr/0012-lists-never-cut-silently.md)).
214
+ A wave with work items that are all merged, done or dropped. Done shows it as one row that opens to its cards, and its **wave band** leaves Todo ([lists never cut silently](docs/adr/2026-10-29-1639-lists-never-cut-silently.md)).
199
215
  _Avoid_: closed wave, archived wave
200
216
 
201
217
  **Work item**:
202
- One unit of work in a wave, usually one PR. Its key is `<wave>/<id>`. It reads as its ticket when the ticket is from the board's source (`#27`, `ENG-12`, `INT-5`), else as its id, and `item add <wave>` takes its id from its ticket ([0132](docs/adr/0132-a-card-is-named-by-its-boards-ticket-source.md)).
218
+ One unit of work in a wave, usually one PR. Its key is `<wave>/<id>`. It reads as its ticket when the ticket is from the board's source (`#27`, `ENG-12`, `INT-5`), else as its id, and `item add <wave>` takes its id from its ticket ([a card is named by its board's ticket source](docs/adr/2026-11-02-2100-a-card-is-named-by-its-boards-ticket-source.md)).
203
219
  _Avoid_: task (a **new task** is the owner's), ticket (the identity of its work in the board’s ticket source)
204
220
 
205
221
  **Ticket**:
206
- The identity of a work item in its board’s **ticket source**, shown as a badge that opens the internal card, GitHub issue or Linear issue. A ticket id belongs to its source: one stored under another source shows as its own id, unlinked. An ask has no ticket; filing it as work creates or links one ([0081](docs/adr/0081-a-board-has-one-ticket-source.md)). A card moves its ticket one way, building to In Progress, a PR to In Review and done to Done, when the owner is assigned it or kickflip created it; a ticket never moves its card ([0088](docs/adr/0088-kickflip-reaches-linear-with-a-key-on-the-mac.md)).
222
+ The identity of a work item in its board’s **ticket source**, shown as a badge that opens the internal card, GitHub issue or Linear issue. A ticket id belongs to its source: one stored under another source shows as its own id, unlinked. An ask has no ticket; filing it as work creates or links one ([a board has one ticket source](docs/adr/2026-11-01-1348-a-board-has-one-ticket-source.md)). A card moves its ticket one way, building to In Progress, a PR to In Review and done to Done, when the owner is assigned it or kickflip created it; a ticket never moves its card ([kickflip reaches Linear with a key on the Mac](docs/adr/2026-11-01-1436-kickflip-reaches-linear-with-a-key-on-the-mac.md)).
207
223
  _Avoid_: card (the board’s work item), task
208
224
 
209
225
  **Ticket source**:
210
- The board’s one choice for every card’s tickets: Internal with a prefix (INT by default), GitHub issues in the board’s repo when it is on GitHub, or a Linear workspace, team and project, picked from dropdowns listed through Hub’s **Linear key**. New board and Board Settings share the choice ([0081](docs/adr/0081-a-board-has-one-ticket-source.md)), and pick Linear only while that key works: tapping Linear without one opens the key’s modal over them. Board Settings saves each change at once, and Done waits for a save in flight ([0117](docs/adr/0117-a-board-picks-linear-only-while-hubs-key-works.md)). A GitHub source can name the gh account its issue calls run as. The hub board’s repo is its entry’s `github`, its folder’s origin, so it can file its cards as GitHub issues ([0115](docs/adr/0115-the-hub-board-files-its-cards-as-github-issues.md)).
226
+ The board’s one choice for every card’s tickets: Internal with a prefix (INT by default), GitHub issues in the board’s repo when it is on GitHub, or a Linear workspace, team and project, picked from dropdowns listed through Hub’s **Linear key**. New board and Board Settings share the choice ([a board has one ticket source](docs/adr/2026-11-01-1348-a-board-has-one-ticket-source.md)), and pick Linear only while that key works: tapping Linear without one opens the key’s modal over them. Board Settings saves each change at once, and Done waits for a save in flight ([a board picks Linear only while Hub's key works](docs/adr/2026-11-02-1712-a-board-picks-linear-only-while-hubs-key-works.md)). A GitHub source can name the gh account its issue calls run as. The hub board’s repo is its entry’s `github`, its folder’s origin, so it can file its cards as GitHub issues ([the hub board files its cards as GitHub issues](docs/adr/2026-11-02-1611-the-hub-board-files-its-cards-as-github-issues.md)).
211
227
  _Avoid_: integration, tracker, GitHub project
212
228
 
213
229
  **Linear key**:
214
- The owner’s Linear personal API key, pasted in Hub settings and kept only on the host; pages learn only whether it is set, whether Linear refused it and its workspace. It saves and is checked with Linear on paste, with no Save button, and the hub remembers a refusal until a call with that key gets an answer ([0117](docs/adr/0117-a-board-picks-linear-only-while-hubs-key-works.md)). kickflip lists teams and projects, creates projects and issues, and moves tickets with it. The hub's poll uses the saved key's viewer as the owner and advances their Linear tickets from PR state, aggregating every carrying card across boards; without a key the poll moves none ([ADR 0107](docs/adr/0107-the-hubs-poll-moves-the-owners-linear-tickets.md)). Without a key, a board can’t pick Linear in Board Settings or New board, and `board.mjs` prints `ticket` lines and the board’s session does that work through its Linear MCP ([0088](docs/adr/0088-kickflip-reaches-linear-with-a-key-on-the-mac.md)).
230
+ The owner’s Linear personal API key, pasted in Hub settings and kept only on the host; pages learn only whether it is set, whether Linear refused it and its workspace. It saves and is checked with Linear on paste, with no Save button, and the hub remembers a refusal until a call with that key gets an answer ([a board picks Linear only while Hub's key works](docs/adr/2026-11-02-1712-a-board-picks-linear-only-while-hubs-key-works.md)). kickflip lists teams and projects, creates projects and issues, and moves tickets with it. The hub's poll uses the saved key's viewer as the owner and advances their Linear tickets from PR state, aggregating every carrying card across boards; without a key the poll moves none ([the hub's poll moves the owner's Linear tickets](docs/adr/2026-11-02-0023-the-hubs-poll-moves-the-owners-linear-tickets.md)). Without a key, no board can pick Linear, and removing the key moves every Linear board to internal tickets; a card is never left without a ticket ([every new card gets a ticket in the board’s current source](docs/adr/2026-11-04-0227-every-new-card-gets-a-ticket-in-the-boards-current-source.md)).
215
231
  _Avoid_: Linear token, API secret
216
232
 
217
233
  **Internal item**:
@@ -219,11 +235,11 @@ A work item about the sites themselves rather than the product. Its legacy ref `
219
235
  _Avoid_: meta task, chore
220
236
 
221
237
  **Badge**:
222
- A chip on a card or page that shows a status, such as Install or a PR's state. It may link to what it is about: on a closed card, Install goes straight to the thing to act on (owner, question `badge-tap`). A card's badges are its ticket ID, wave chip, follow-up, risky, New on an unsorted ask, and PR and try-build state; held, blocked by and Action needed are orange words on its time line instead, and ready a green one, and a bump shows only as the filled bump icon ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)). A badge never acts on the board; a **button** does.
238
+ A chip on a card or page that shows a status, such as Install or a PR's state. It may link to what it is about: on a closed card, Install goes straight to the thing to act on (owner, question `badge-tap`). A card's badges are its ticket ID, wave chip, risky, New on an unsorted ask, and PR and try-build state; held, blocked by and Action needed are orange words on its time line instead, and ready a green one, and a bump shows only as the filled bump icon ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)). A badge never acts on the board; a **button** does.
223
239
  _Avoid_: chip (in what the owner reads), tag, label
224
240
 
225
241
  **Button**:
226
- A control that acts: it sends something to the board, such as Merge, Hold or Grill, or opens a place to act, such as Open questions. The open card's workflow row holds Merge, Hold or Unhold, the **action button**, Serve or Build when the card has a build script and branch changes and Auto-build is off, and last **Implement** on a Todo card that can start (a held Todo card's Implement takes the place of its Unhold), below the details list whose final line holds Notes, Install and Review on GitHub links in that order ([0067](docs/adr/0067-a-cards-external-links-share-the-last-details-line.md)). A card that can be bumped, every Todo card (held or waiting on the owner included) and a running In Progress one that isn't held, carries its bump as an icon at its top right instead, closed or open, as a New card does (the empty icon always shows on a touch screen and with a mouse only while the card is hovered or has focus; a bumped card's filled one always shows) ([0019](docs/adr/0019-a-card-that-hasnt-started-can-be-bumped.md)). It sends with no confirm, and on a bumped card it is filled orange and unbumps (`card-unbump {key}`) ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)). The control that clears the card's **Action needed** is orange.
242
+ A control that acts: it sends something to the board, such as Merge, Hold or Grill, or opens a place to act, such as Open questions. The open card's workflow row holds Merge, Hold or Unhold, the **action button**, Serve or Build when the card has a build script and branch changes and Auto-build is off, and last **Implement** on a Todo card that can start (a held Todo card's Implement takes the place of its Unhold), below the details list whose final line holds Notes, Install and Review on GitHub links in that order ([a card's external links share the last details line](docs/adr/2026-10-30-2008-a-cards-external-links-share-the-last-details-line.md)). A card that can be bumped, every Todo card (held or waiting on the owner included) and a running In Progress one that isn't held, carries its bump as an icon at its top right instead, closed or open, as a New card does (the empty icon always shows on a touch screen and with a mouse only while the card is hovered or has focus; a bumped card's filled one always shows) ([a card that hasn't started, or is running, can be bumped](docs/adr/2026-10-29-1639-a-card-that-hasnt-started-can-be-bumped.md)). It sends with no confirm, and on a bumped card it is filled orange and unbumps (`card-unbump {key}`) ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)). The control that clears the card's **Action needed** is orange.
227
243
  _Avoid_: badge, pill (a pill is only a look)
228
244
 
229
245
  **Badge tone**:
@@ -231,43 +247,47 @@ The color of a badge (a status chip on a card or page), picked from one fixed se
231
247
  _Avoid_: chip color, badge style, variant
232
248
 
233
249
  **Status color**:
234
- A color named by what it means, `--color-quiet`, `--color-info`, `--color-notice`, `--color-danger` or `--color-success`, in `shared/colors.css` beside the base palette, in light and dark. That file is the one set of colors for the hub and every board; no page's CSS defines a color of its own ([0033](docs/adr/0033-one-colour-constants-file-shared-by-the-hub-and-every-board.md)). Which one a meaning takes follows the **colour rule**; done or passing is success.
250
+ A color named by what it means, `--color-quiet`, `--color-info`, `--color-notice`, `--color-danger` or `--color-success`, in `shared/colors.css` beside the base palette, in light and dark. That file is the one set of colors for the hub and every board; no page's CSS defines a color of its own ([one colour constants file shared by the hub and every board](docs/adr/2026-10-29-1639-one-colour-constants-file-shared-by-the-hub-and-every-board.md)). Which one a meaning takes follows the **colour rule**; done or passing is success.
235
251
  _Avoid_: tone token, theme color, badge color
236
252
 
237
253
  **Colour rule**:
238
- A colour says whose turn it is: red (danger) for faults, such as failed, down, not listening or spending, and the sidebar's "N need you"; orange (notice) for attention and work, such as Action needed, the Needs you box, a New card, a Next line while it is someone's turn, a builder's line, Working or Starting; blue (info) only for review and notice, something for the owner to read or see, such as an unread review, a new version to reload or a changed line's flash; grey (quiet) for idle, such as ticket ids, a Todo or Done card's Next, the Done ring, Stopped or usage that is fine, which takes no other colour. Pick a new colour by it ([0096](docs/adr/0096-colour-says-whos-waiting.md)).
254
+ A colour says whose turn it is: red (danger) for faults, such as failed, down, not listening or spending, and the sidebar's "N need you"; orange (notice) for attention and work, such as Action needed, the Needs you box, a New card, a Next line while it is someone's turn, a builder's line, Working or Starting; blue (info) only for review and notice, something for the owner to read or see, such as an unread review, a new version to reload or a changed line's flash; grey (quiet) for idle, such as ticket ids, a Todo or Done card's Next, the Done ring, Stopped or usage that is fine, which takes no other colour. Pick a new colour by it ([colour says who's waiting](docs/adr/2026-11-01-1817-colour-says-whos-waiting.md)).
239
255
  _Avoid_: warning colour (for attention), action colour (for blue)
240
256
 
241
257
  **Follow-up**:
242
- A work item with a **Parent**: work spun out of another card. It is an ordinary card in every way and carries the quiet follow-up badge ([0156](docs/adr/0156-a-follow-up-is-a-work-card-with-a-parent.md)).
258
+ A work item with a **Parent**: work spun out of another card. It is an ordinary card in every way, shown only by its Parent link ([a follow-up is a work card with a Parent](docs/adr/2026-11-03-0526-a-follow-up-is-a-work-card-with-a-parent.md)).
243
259
  _Avoid_: backlog item, todo, follow-up tag
244
260
 
245
261
  **Parent**:
246
- The one card a work item was spun out of, or none: set when a card is created from another card's conversation (its thread, a grill or an answer) with `item add --parent`, none for a card from the + or New task. The Parent lists it among its **Children**. The open card shows both as rows of card labels, with **Related to**, Blocked by and Waits on it, the mirror of Blocked by ([0156](docs/adr/0156-a-follow-up-is-a-work-card-with-a-parent.md)).
262
+ The one card a work item was spun out of, or none: set when a card is created from another card's conversation (its thread, a grill or an answer) with `item add --parent`, none for a card from the + or New task. The Parent lists it among its **Children**. The open card shows both as rows of card labels, with **Related to**, Blocked by and Waits on it, the mirror of Blocked by ([a follow-up is a work card with a Parent](docs/adr/2026-11-03-0526-a-follow-up-is-a-work-card-with-a-parent.md)).
247
263
  _Avoid_: filed from, origin, epic
248
264
 
249
265
  **Related to**:
250
- Similar cards that should be cross-referenced, set by hand with `item set --related`, shown on both cards. It neither blocks nor orders anything; Blocked by does that ([0020](docs/adr/0020-cards-wait-on-explicit-blocked-by-links.md)).
266
+ Similar cards that should be cross-referenced, set by hand with `item set --related`, shown on both cards. It neither blocks nor orders anything; Blocked by does that ([cards wait on explicit blocked-by links](docs/adr/2026-10-29-1639-cards-wait-on-explicit-blocked-by-links.md)).
251
267
  _Avoid_: sibling, link (alone)
252
268
 
253
269
  **Plan waves**:
254
- The Show more row at the foot of Todo, shown when two or more work cards there are neither held nor blocked. Confirming sends `plan-waves {keys}`, and the session triages those cards into one or more lineups and asks to confirm each as a board question ([0153](docs/adr/0153-plan-waves-plans-from-any-todo-cards.md)).
270
+ The Show more row at the foot of Todo, shown when two or more work cards there are neither held nor blocked. Confirming sends `plan-waves {keys}`, and the session triages those cards into one or more lineups and asks to confirm each as a board question ([Plan waves plans from any Todo cards](docs/adr/2026-11-03-0509-plan-waves-plans-from-any-todo-cards.md)).
255
271
  _Avoid_: backlog item, todo
256
272
 
273
+ **Done archive**:
274
+ `data/done-archive.json`, where a finished work card goes once 100 newer Done cards close, with its resolved questions and the asks it was made from, unless a lineup band, an unfinished card or an open question still needs it. The board build never reads it. The Done list pages it in 100 at a time as Show more reaches the cards the page holds, each card built as it pages in ([archived Done cards are built as they page in](docs/adr/2026-11-04-1056-archived-done-cards-are-built-as-they-page-in.md)), and a command that names an archived card brings it back to its wave file. Its thread stays whole ([the board keeps the newest 100 Done cards, and older ones page in from an archive](docs/adr/2026-11-04-0307-the-board-keeps-the-newest-100-done-cards.md)).
275
+ _Avoid_: history, old cards
276
+
257
277
  **Lane**:
258
- Where a card sits (In Review, Stale, In Progress, Todo, Done, Asks), set by who acts next ([0045](docs/adr/0045-the-lane-follows-who-acts-next.md)). In Progress means a card is building: a running build agent, a **checking** item, or a PR whose CI is red or, on a draft, still running. A work card that has started building, with a build agent's record, running or finished, a building or fixing status, or a **queued build** ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)), never drops back to Todo unless held ([0138](docs/adr/0138-a-card-moves-to-in-progress-only-once-building-starts.md)). A running grill or prototype agent shows its status line but leaves the card where it is. In Review means finished work waits on a person: the reviewers, or the owner's Ready, Merge, manual steps or the Done of an ask (see **Action needed**), or of a reopened card. An owner message or a new question on a Done card that hasn't merged reopens it: In Progress until Claude answers, then In Review until the owner's Done, its next step "Tap Done once it is settled" ([0128](docs/adr/0128-a-message-or-question-on-a-done-card-reopens-it.md), [0136](docs/adr/0136-a-card-waiting-only-to-be-closed-has-no-action-needed.md)). A card waiting only on those moves there from In Progress; one Claude still works on stays in In Progress. Todo holds work that hasn't started building: the New cards, which wait on Claude ([0047](docs/adr/0047-the-plus-makes-a-new-card.md)), and every work card with no build yet, where its **Implement** shows. Discussion keeps a card there: open questions or a prototype pick, with Action needed, answered or resolved questions, grill and prototype agents, a working mark on a message in its thread and a prototype recorded for it ([0138](docs/adr/0138-a-card-moves-to-in-progress-only-once-building-starts.md)). A started card that gets a question keeps its lane ([0059](docs/adr/0059-an-unstarted-card-waits-on-its-questions-in-todo.md)). Each lane has one fixed order, with no sort menu ([0140](docs/adr/0140-each-lane-has-one-fixed-order.md)): Todo lists its New cards first, oldest first, then its bumped cards, the latest bump on top ([0019](docs/adr/0019-a-card-that-hasnt-started-can-be-bumped.md)), then the rest newest made first; In Progress, its bumped cards first, then by when each came into the lane, its reopening or its latest build agent's start, the newest arrival on top; In Review and Stale by when the PR was first sent to a reviewer, the newest on top; Done by when each card closed, the most recent on top; Asks, the answered asks in their own lane below Done, by when Claude answered, the newest on top. Done and Asks each show 10 cards, then a Show more, the thread's, that adds 10 and says how many are left; a card the owner has open stays shown ([0144](docs/adr/0144-answered-asks-have-their-own-section-below-done.md)). Every card, a New card included, ends with one muted line holding the time its lane sorts by: the time only today, the day too before today ("10/31, 2:49 PM"), and the year too past 365 days. A card with no such time has no time on that line.
278
+ Where a card sits (In Review, Stale, In Progress, Todo, Done, Asks), set by who acts next ([the lane follows who acts next, and a card waiting on the owner says Action needed](docs/adr/2026-10-29-1639-the-lane-follows-who-acts-next.md)). In Progress means a card is building: a running build agent, a **checking** item, or a ready PR whose CI is red, or a red draft on a board that **skips the draft**. A work card that has started building, with a build agent's record, running or finished, a building or fixing status, or a **queued build** ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)), never drops back to Todo unless held ([a card moves to In Progress only once building starts](docs/adr/2026-11-03-0202-a-card-moves-to-in-progress-only-once-building-starts.md)). A running grill or prototype agent shows its status line but leaves the card where it is. In Review means finished work waits on a person: the reviewers, or the owner's review of a draft ("Review draft PR #n", whatever its CI), Merge, manual steps or the Done of an ask (see **Action needed**), or of a reopened card. An owner message or a new question on a Done card, merged or not, reopens it: In Progress until Claude answers, then In Review until the owner's Done, its next step "Tap Done once it is settled" ([a message or question on a Done card reopens it until the owner's Done](docs/adr/2026-11-02-1952-a-message-or-question-on-a-done-card-reopens-it.md), [a merged card reopens on a message, and its PR badge shows the PR's state](docs/adr/2026-11-03-1843-a-merged-card-reopens-and-its-pr-badge-shows-the-prs-state.md), [a card waiting only to be closed has no Action needed](docs/adr/2026-11-03-0137-a-card-waiting-only-to-be-closed-has-no-action-needed.md)). A card waiting only on those moves there from In Progress; one Claude still works on stays in In Progress. A card with several PRs, in any repos, sits where its least-ready PR puts it, shows a PR badge for each, and is Done once every PR has merged or closed with at least one merged ([a card holds several PRs across repos](docs/adr/2026-11-03-1904-a-card-holds-several-prs-across-repos.md)). Todo holds work that hasn't started building: the New cards, which wait on Claude ([the + makes a New card, which Claude files, folds or answers](docs/adr/2026-10-29-1639-the-plus-makes-a-new-card.md)), and every work card with no build yet, where its **Implement** shows. Discussion keeps a card there: open questions or a prototype pick, with Action needed, answered or resolved questions, grill and prototype agents, a working mark on a message in its thread and a prototype recorded for it ([a card moves to In Progress only once building starts](docs/adr/2026-11-03-0202-a-card-moves-to-in-progress-only-once-building-starts.md)). A started card that gets a question keeps its lane ([an unstarted card waits on its questions in Todo, and its one action button follows what it waits on](docs/adr/2026-10-30-1309-an-unstarted-card-waits-on-its-questions-in-todo.md)). Each lane has one fixed order, with no sort menu ([each lane has one fixed order](docs/adr/2026-11-03-0223-each-lane-has-one-fixed-order.md)): Todo lists its New cards first, oldest first, then its bumped cards, the latest bump on top ([a card that hasn't started, or is running, can be bumped](docs/adr/2026-10-29-1639-a-card-that-hasnt-started-can-be-bumped.md)), then the rest newest made first; In Progress, its bumped cards first, then by when each came into the lane, its reopening or its latest build agent's start, the newest arrival on top; In Review and Stale by when the PR was first sent to a reviewer, the newest on top; Done by when each card closed, the most recent on top; Asks, the answered asks in their own lane below Done, by when Claude answered, the newest on top. Done and Asks each show 10 cards, then a Show more, the thread's, that adds 10 and says how many are left; a card the owner has open stays shown ([answered asks have their own section below Done, and Done and Asks show 10 cards at a time](docs/adr/2026-11-03-0259-answered-asks-have-their-own-section-below-done.md)). Every card, a New card included, ends with one muted line holding the time its lane sorts by: the time only today, the day too before today ("10/31, 2:49 PM"), and the year too past 365 days. A card with no such time has no time on that line.
259
279
  _Avoid_: column, status (status is the item's own field)
260
280
 
261
281
  **Checking**:
262
- The item status a site card's builder sets when it hands back finished work it couldn't land itself. The card sits in In Progress reading "Orchestrator review" while the owning session verifies and lands it. Only done, merged and dropped unblock dependents ([0022](docs/adr/0022-site-cards-build-in-parallel-when-their-files-dont-overlap.md), [0133](docs/adr/0133-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)).
282
+ The item status a builder's `builder done` sets when it hands back finished work with unverified judgment calls, including one naming why it couldn't finish. The card sits in In Progress reading "Orchestrator review" while the owning session verifies the calls; its `builder verified` **finishes** the card ([finishing a build is one step](docs/adr/2026-11-04-1611-finishing-a-build-is-one-step.md)). Only done, merged and dropped unblock dependents ([site cards build in parallel when their files don't overlap](docs/adr/2026-10-29-1639-site-cards-build-in-parallel-when-their-files-dont-overlap.md), [the board records what it knows, and commands make the rule calls](docs/adr/2026-11-03-0003-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)).
263
283
  _Avoid_: verifying, in QA, review (review is the reviewers' part)
264
284
 
265
285
  **Stale**:
266
- A work item that has waited in review more than seven days since its first review link went out. Its card moves to the Stale lane ([0044](docs/adr/0044-a-pr-in-review-shows-its-age-and-goes-stale-after-seven-days.md)).
286
+ A work item that has waited in review more than seven days since its first review link went out. Its card moves to the Stale lane ([a PR in review shows its age, and goes Stale after seven days](docs/adr/2026-10-29-1639-a-pr-in-review-shows-its-age-and-goes-stale-after-seven-days.md)).
267
287
  _Avoid_: old, overdue
268
288
 
269
289
  **Next step**:
270
- Claude's next step on a card and what sets it off, such as "Next: merge when CI is green", kept in the item's `next` and cleared once done. A card waiting on its reviewers reads its next step from GitHub instead ([0002](docs/adr/0002-a-card-derives-its-lane-from-github.md)), and one waiting on the owner reads its action. It is orange while it is someone's turn and grey on a Todo, Done or held card. It shares its place under the title with the builder line, which takes it while a builder record is open, and an In Progress card with neither reads "Next: none set yet": the CLI refuses a `builder done` or `item set` that would leave one so without `--next` ([0142](docs/adr/0142-an-in-progress-card-always-has-a-builder-line-or-a-next.md)). A Next set while the card has an open question clears once a build starts on it, or once Claude's acting leaves none of its questions unresolved ([0157](docs/adr/0157-an-answer-stops-waiting-once-its-acted-on.md)).
290
+ Claude's next step on a card and what sets it off, such as "Next: merge when CI is green", kept in the item's `next` and cleared once done. A card waiting on its reviewers reads its next step from GitHub instead ([a card derives its lane and its review next step from GitHub, never from a kept status](docs/adr/2026-10-29-1639-a-card-derives-its-lane-from-github.md)), and one waiting on the owner reads its action. It is orange while it is someone's turn and grey on a Todo, Done or held card. It shares its place under the title with the builder line, which takes it while a builder record is open, and an In Progress card with neither reads "Next: none set yet": the CLI refuses a `builder done` or `item set` that would leave one so without `--next` ([an In Progress card always has a builder line or a Next](docs/adr/2026-11-03-0237-an-in-progress-card-always-has-a-builder-line-or-a-next.md)). A Next set while the card has an open question clears once a build starts on it, or once Claude's acting leaves none of its questions unresolved ([an answer stops waiting once it's acted on, and a Next set during the card's questions clears](docs/adr/2026-11-03-1313-an-answer-stops-waiting-once-its-acted-on.md)).
271
291
  _Avoid_: plan, notes (**Notes** is the card's write-up), todo
272
292
 
273
293
  **Waits on**:
@@ -275,112 +295,137 @@ Who the card is waiting for: the owning session's check, the owner's Ready, the
275
295
  _Avoid_: blocked by, assignee
276
296
 
277
297
  **Card state**:
278
- What a card made from a **New task** does next, which its session picks and sets with `item set --state`: **ready** (its notes leave the owner nothing to decide, so it can be built; the plan lives only in the notes), **grilling** (questions on the card) or **prototyping** (takes on the card). The board enforces the three: `--state` refuses any other, and ready while the card has an open question. Until it has one, the card reads New beside its ticket id and is never pulled. A Ready card's time line reads a green "ready" in Action needed's place ("10:26 · held · ready · 2 new messages") while nothing blocks it and nothing waits on the owner, and the idle pull takes it like any settled card ([0154](docs/adr/0154-a-new-card-is-ready-grilling-or-prototyping.md)).
298
+ What a card made from a **New task** does next, which its session picks and sets with `item set --state`: **ready** (its notes leave the owner nothing to decide, so it can be built; the plan lives only in the notes), **grilling** (questions on the card) or **prototyping** (takes on the card). The board enforces the three: `--state` refuses any other, and ready while the card has an open question. Until it has one, the card reads New beside its ticket id and is never pulled. A Ready card's time line reads a green "ready" in Action needed's place ("10:26 · held · ready · 2 new messages") while nothing blocks it and nothing waits on the owner, and the idle pull takes it like any settled card ([a new card is ready, grilling or prototyping, and reads ready in green when it is](docs/adr/2026-11-03-0516-a-new-card-is-ready-grilling-or-prototyping.md)).
279
299
  _Avoid_: triage state, status (the wave entry's `status` is a different field)
280
300
 
281
301
  **Action needed**:
282
- The orange words last among the orange ones on a card's time line ("10:26 · held · blocked by #53 · Action needed"), on a card waiting on the owner, in any lane ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)): an open question or a prototype pick, a green draft's Ready, the Done of an ask, manual steps on an approved PR, or, with **auto-merge** off, an approved PR's Merge. It links to the thing to act on. Reviewer waits and held cards get none ([0045](docs/adr/0045-the-lane-follows-who-acts-next.md)), and so does a reopened card waiting only on the owner's Done, which is only waiting to be closed ([0136](docs/adr/0136-a-card-waiting-only-to-be-closed-has-no-action-needed.md)). An unstarted card with open questions carries it in Todo ([0059](docs/adr/0059-an-unstarted-card-waits-on-its-questions-in-todo.md)).
302
+ The orange words last among the orange ones on a card's time line ("10:26 · held · blocked by #53 · Action needed"), on a card waiting on the owner, in any lane ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)): an open question or a prototype pick, a green draft's Ready, the Done of an ask, manual steps on an approved PR, or, with **auto-merge** off, an approved PR's Merge. It links to the thing to act on. Reviewer waits and held cards get none ([the lane follows who acts next, and a card waiting on the owner says Action needed](docs/adr/2026-10-29-1639-the-lane-follows-who-acts-next.md)), and so does a reopened card waiting only on the owner's Done, which is only waiting to be closed ([a card waiting only to be closed has no Action needed](docs/adr/2026-11-03-0137-a-card-waiting-only-to-be-closed-has-no-action-needed.md)). An unstarted card with open questions carries it in Todo ([an unstarted card waits on its questions in Todo, and its one action button follows what it waits on](docs/adr/2026-10-30-1309-an-unstarted-card-waits-on-its-questions-in-todo.md)).
283
303
  _Avoid_: open items, needs you (Needs you is the box at the top of the board)
284
304
 
305
+ **Request**:
306
+ The owner's ask for a grill or a prototype on a card: the thread composer's fire or eye, toggles that Send carries, or /grill or /prototype typed in the box, sending `grill-more` or `prototype-request` with whatever was typed; a question's own eye on Waiting on you asks for a prototype of that question. A request with nothing typed is one gray **status line** in the thread, "grill requested" or "prototype requested"; one with text is the owner's message carrying it, with that status in the message's footer, and "Waiting for Claude…" to its right until Claude picks it up. An answer submitted from Waiting on you is likewise a message whose footer reads "answers submitted". A question asked for a prototype reads "prototype requested", locked, until a question naming it in `round_of` resolves it, and `question resolve` refuses it; a prototype request still waiting 30 minutes on with no prototype agent running comes back to the session as `prototype-overdue` ([a button tap is a status line or a message footer](docs/adr/2026-11-04-2130-a-button-tap-is-a-status-line-or-a-message-footer.md), [a prototype request waits for its prototype](docs/adr/2026-11-04-2130-a-prototype-request-waits-for-its-prototype.md)).
307
+ _Avoid_: Grill button, Prototype button (on a card)
308
+
285
309
  **Action button**:
286
- The open card's one workflow button, which `board/domain.mjs` picks as the card's `actionButton`: **Open questions** (`openQuestions`) while it has open questions or a prototype pick, opening the first; **Mark as done** (`markDone`) on an ask waiting on the owner's Done, sending the same `ask-done` as the thread's Done; otherwise **Grill** (`grill`), which reads "Writing questions…", disabled, while a grill is under way: a Grill tap Claude hasn't answered, a running grill agent, or a **grilling** card with no questions posted yet ([0154](docs/adr/0154-a-new-card-is-ready-grilling-or-prototyping.md)). Open questions win over Mark as done. A Done card, and an ask with neither, has none ([0059](docs/adr/0059-an-unstarted-card-waits-on-its-questions-in-todo.md)).
287
- While the card carries **Action needed**, the button that clears it is orange, in the notice color: the card's `resolvedBy` from `board/domain.mjs`, by the action's kind. A question or a pick makes Open questions orange, the Done of an ask makes Mark as done and the thread's Done orange, a green draft's Ready or manual steps make Review on GitHub orange, and an approved PR's Merge makes Merge orange. A held card's Open questions, and Grill, stay plain. A reopened card waiting only on the owner's Done keeps Grill, and its thread's Done is primary, in the accent color ([0136](docs/adr/0136-a-card-waiting-only-to-be-closed-has-no-action-needed.md)).
310
+ The open card's one workflow button, which `board/domain.mjs` picks as the card's `actionButton`: **Open questions** (`openQuestions`) while it has open questions or a prototype pick, opening the first; **Mark as done** (`markDone`) on an ask waiting on the owner's Done, sending the same `ask-done` as the thread's Done; otherwise none. A grill or prototype is asked for from the thread's fire and eye (**request**), and the card reads a blue planner line "preheating" while a grill is under way: a grill request not yet handled (replied to, questions posted on the card after it, or a grill agent started after it finished), a running grill agent, or a **grilling** card with no questions posted yet ([a new card is ready, grilling or prototyping, and reads ready in green when it is](docs/adr/2026-11-03-0516-a-new-card-is-ready-grilling-or-prototyping.md)). Open questions win over Mark as done. A Done card has none ([an unstarted card waits on its questions in Todo, and its one action button follows what it waits on](docs/adr/2026-10-30-1309-an-unstarted-card-waits-on-its-questions-in-todo.md)).
311
+ While the card carries **Action needed**, the button that clears it is orange, in the notice color: the card's `resolvedBy` from `board/domain.mjs`, by the action's kind. A question or a pick makes Open questions orange, the Done of an ask makes Mark as done and the thread's Done orange, a green draft's Ready or manual steps make Review on GitHub orange, and an approved PR's Merge makes Merge orange. A held card's Open questions stay plain. A reopened card waiting only on the owner's Done has its thread's Done primary, in the accent color ([a card waiting only to be closed has no Action needed](docs/adr/2026-11-03-0137-a-card-waiting-only-to-be-closed-has-no-action-needed.md)).
288
312
  The button names (`BUTTON`: the action buttons, `github` and `merge`) and the action kinds (`ACTION_KIND`) are two frozen enums in `board/public/ui-enums.js`, which the page loads as a script and `board/domain.mjs` runs in a vm context; code compares against their members, never a bare string.
289
313
  _Avoid_: Open items, Action needed (the badge)
290
314
 
291
315
  **GitHub tick**:
292
- The session's steps for PR comments, CI, review, conflicts and merging, defined in SKILL.md. The hub polls GitHub with Node and gh, writes new owner and reviewer comments into each card's thread, closes a card whose PR merged, then wakes the board on a change ([0134](docs/adr/0134-the-hubs-poll-records-merges-and-pr-comments-on-the-card.md)); the tick reads each card with `board.mjs pr` and records the newest handled event with `item set --gh-since`. With Hub's Linear key set, the poll also moves the owner's Linear tickets from PR state, so the session leaves those moves to the hub; without a key the poll moves none ([ADR 0107](docs/adr/0107-the-hubs-poll-moves-the-owners-linear-tickets.md)). The owner's monitor skill is optional ([0103](docs/adr/0103-the-hub-reads-github-itself.md)).
316
+ The session's steps for PR comments, CI, review, conflicts and merging, defined in SKILL.md. The hub polls GitHub with Node and gh, writes new owner and reviewer comments into each card's thread, closes a card whose PR merged, then wakes the board on a change ([the hub's poll records merges and PR comments on the card](docs/adr/2026-11-02-2335-the-hubs-poll-records-merges-and-pr-comments-on-the-card.md)); the tick reads each card with `board.mjs pr` and records the newest handled event with `item set --gh-since`. With Hub's Linear key set, the poll also moves the owner's Linear tickets from PR state, so the session leaves those moves to the hub; without a key the poll moves none ([the hub's poll moves the owner's Linear tickets](docs/adr/2026-11-02-0023-the-hubs-poll-moves-the-owners-linear-tickets.md)). The owner's monitor skill is optional ([the hub reads GitHub itself](docs/adr/2026-11-01-2314-the-hub-reads-github-itself.md)).
293
317
 
294
318
  **Auto-merge**:
295
- A board setting, `auto_merge` in its `board.json`, off unless set: on, the session's GitHub tick merges a PR once it is approved, CI is green and its merge state is CLEAN; off, the card shows the owner Action needed and a Merge button, which reads "Merging…" until the PR merges or Claude says in the thread why it didn't. The board's Settings modal toggles it, and the watcher prints it with every wake as `setting auto-merge on|off`. A setting, not a **rule**, since the board itself acts on it ([0052](docs/adr/0052-auto-merge-is-a-board-setting-off-by-default.md)).
319
+ A board setting, `auto_merge` in its `board.json`, off unless set: on, the hub's GitHub tick merges a PR once it is approved, CI is green and its merge state is CLEAN; off, the card shows the owner Action needed and a Merge button, which reads "Merging…" until the board server merges the PR or says in the thread why it didn't. The board's Settings modal toggles it, and the watcher prints it with every wake as `setting auto-merge on|off`. A setting, not a **rule**, since the board itself acts on it ([Auto-merge is a board setting, off by default, and the owner merges from the card](docs/adr/2026-10-29-1752-auto-merge-is-a-board-setting-off-by-default.md)).
296
320
  _Avoid_: merge rule, merge policy
297
321
 
322
+ A card with no PR lands the same way: with Auto-merge off its builder's `done` stops after the tests, and the card waits in In Review with a Merge button; the tap makes the board server rebase it onto main as it is now, rerun the tests and land it, sending a conflict or a failing test to a headless lander ([a land waits for your Merge](docs/adr/2026-11-04-2100-a-land-waits-for-your-merge.md)).
323
+
324
+ **PRs**:
325
+ A board setting, `prs` in its `board.json`, on unless set, shown on a GitHub board that builds in its own clone only. On, every card opens a PR, and with no reviewers on the board that PR merges once it is green and clean, with no approval. Off, no PR opens and each card lands on main, which is pushed; Skip the draft and Reviewers are hidden, and turning it off needs Push main granted ([a land waits for your Merge](docs/adr/2026-11-04-2100-a-land-waits-for-your-merge.md)).
326
+ _Avoid_: PR mode, no-PR mode
327
+
328
+ **Skip the draft**:
329
+ A board setting, `skip_draft` in its `board.json`, off unless set, shown on a GitHub board only. On, the hub's GitHub check marks a card's draft PR ready for review once its CI passes, and the card waits in In Review with no Action needed until then; off, the draft waits in In Review with Action needed "Review draft PR #n". With **Auto-merge** on too, a builder's PR can merge once reviewers approve it, without the owner seeing it ([a board can skip the draft](docs/adr/2026-11-04-1913-a-board-can-skip-the-draft.md)).
330
+ _Avoid_: auto-ready, skip review
331
+
298
332
  **Review on GitHub**:
299
- The open card's link to its PR, on every card with an open PR, last on the details list's final line after Notes and Install when present. It reads "Review draft on GitHub ↗" on a draft and "Review on GitHub ↗" once ready, with no PR number, and is orange while a green draft's Ready or manual steps wait on the owner ([0067](docs/adr/0067-a-cards-external-links-share-the-last-details-line.md)).
333
+ The open card's link to its PR, on every card with an open PR, last on the details list's final line after Notes and Install when present. It reads "Review draft on GitHub ↗" on a draft and "Review on GitHub ↗" once ready, with no PR number, and is orange while a green draft's Ready or manual steps wait on the owner ([a card's external links share the last details line](docs/adr/2026-10-30-2008-a-cards-external-links-share-the-last-details-line.md)).
300
334
  _Avoid_: Review #<n> on GitHub, PR link
301
335
 
302
336
  **Install**:
303
- The app card's one badge that opens its build on the owner's phone, or the badge on main's slim bar above the lanes. A ready card reads "Install ↗", or "Install (stale) ↗" when its build's sha differs from the current branch head. While a build runs it reads "Building…" with an inert spinner; a failed build reads "Build failed ↗" and opens its thread. The open card's badge sits between Notes and Review on GitHub. The workflow button starts a Build, or Retry after failure, while Auto-build is off and the card's branch has changes ([0124](docs/adr/0124-only-the-owner-or-auto-build-starts-a-card-run.md)). Main’s red Build failed button opens a bottom sheet with the last 40 lines of `data/try/main.log` and Retry at the recorded failed tip. Retry shows readiness refusals in the sheet, reads Building… in orange while running, refreshes the log after failure and closes with a toast when ready. A Done card has no try badge ([0099](docs/adr/0099-a-boards-build-script-serves-or-builds-each-card-and-main.md)).
337
+ The app card's one badge that opens its build on the owner's phone, or the badge on main's slim bar above the lanes. A ready card reads "Install ↗", or "Install (stale) ↗" when its build's sha differs from the current branch head. While a build runs it reads "Serving…" with an inert spinner; a failed build reads "Serve failed ↗" and opens its thread. The open card's badge sits between Notes and Review on GitHub. The workflow button starts a Serve, or Retry after failure, while Auto serve is off and the card's branch has changes ([only the owner or Auto serve starts a card run](docs/adr/2026-11-02-1806-only-the-owner-or-auto-build-starts-a-card-run.md)). Main’s red Build failed button opens a bottom sheet with the last 40 lines of `data/try/main.log` and Retry at the recorded failed tip. Retry shows readiness refusals in the sheet, reads Building… in orange while running, refreshes the log after failure and closes with a toast when ready. On a local board, a refresh icon right of main's timestamp pulls its branch from origin now, as every poll does, and turns red with the reason when a pull can't fast-forward ([a local board's Main pulls from origin on its own](docs/adr/2026-11-03-1914-a-local-boards-main-pulls-from-origin-on-its-own.md)). A Done card has no try badge ([a board's build script serves or builds each card and main](docs/adr/2026-11-01-1846-a-boards-build-script-serves-or-builds-each-card-and-main.md)).
304
338
  _Avoid_: download, TestFlight (a different channel), older build
305
339
 
306
340
  **Build script**:
307
- The repo's reviewed, executable `.kickflip/build`, run by the hub from each card's worktree and main's hub-owned detached worktree. The hub passes the key (or `main`) and worktree, plus `KICKFLIP_BOARD`. Websites serve at their root on their own Tailscale HTTPS port, without a path prefix or `KICKFLIP_BASE` ([0102](docs/adr/0102-a-try-build-serves-on-its-own-tailscale-port.md)). Printing `port <n>` and staying alive serves a website; exiting 0 without a port finishes an app build that publishes an install through the board CLI. The last finished run decides the board's kind. The hub writes try state and logs; failed card runs append one thread line, and successful runs none. There is no script path setting ([0099](docs/adr/0099-a-boards-build-script-serves-or-builds-each-card-and-main.md)).
341
+ The repo's reviewed, executable `.kickflip/build`, run by the hub from each card's worktree and main's hub-owned detached worktree. The hub passes the key (or `main`) and worktree, plus `KICKFLIP_BOARD`. Websites serve at their root on their own Tailscale HTTPS port, without a path prefix or `KICKFLIP_BASE` ([a try build serves on its own Tailscale port](docs/adr/2026-11-01-2254-a-try-build-serves-on-its-own-tailscale-port.md)). Printing `port <n>` and staying alive serves a website; exiting 0 without a port finishes an app build that publishes an install through the board CLI. The last finished run decides the board's kind. The hub writes try state and logs; failed card runs append one thread line, and successful runs none. There is no script path setting ([a board's build script serves or builds each card and main](docs/adr/2026-11-01-1846-a-boards-build-script-serves-or-builds-each-card-and-main.md)).
308
342
  _Avoid_: install script, session install runner
309
343
 
310
344
  **Serve**:
311
- The workflow button after the **action button** for a website work card with a build script, last but for **Implement**, while Auto-build is off and the card's branch has changes ([0124](docs/adr/0124-only-the-owner-or-auto-build-starts-a-card-run.md)). It confirms before the hub runs the script. Its one badge reads "Serving…", "Visit ↗", "Visit (stale) ↗" or "Serve failed ↗". A served card opens at `https://<host>:<port>/`, with a port from 8500–8599 kept through re-serves. A loopback relay tracks visits; 30 idle minutes stops the card and releases its port. Main has a fixed port recorded per board, keeps its link across merges and restarts and never idles out. Its red Serve failed button opens the same log and Retry sheet as an app’s Build failed, reading Serving… in orange while retrying the recorded failed tip, even if origin has moved. Both open the server itself, outside the app shell ([0102](docs/adr/0102-a-try-build-serves-on-its-own-tailscale-port.md)).
345
+ The workflow button after the **action button** for a website work card with a build script, last but for **Implement**, while Auto serve is off and the card's branch has changes ([only the owner or Auto serve starts a card run](docs/adr/2026-11-02-1806-only-the-owner-or-auto-build-starts-a-card-run.md)). It confirms before the hub runs the script. Its one badge reads "Serving…", "Visit ↗", "Visit (stale) ↗" or "Serve failed ↗". A served card opens at `https://<host>:<port>/`, with a port from 8500–8599 kept through re-serves. A loopback relay tracks visits; 30 idle minutes stops the card and releases its port. Main has a fixed port recorded per board, keeps its link across merges and restarts and never idles out. Its red Serve failed button opens the same log and Retry sheet as an app’s, reading Serving… in orange while retrying the recorded failed tip, even if origin has moved. Both open the server itself, outside the app shell ([a try build serves on its own Tailscale port](docs/adr/2026-11-01-2254-a-try-build-serves-on-its-own-tailscale-port.md)).
312
346
  _Avoid_: preview site, separate page
313
347
 
314
- **Auto-build**:
315
- The board's `auto_build` setting, off by default. On, each card with commits beyond main builds or serves after each new head, and cards show no Serve or Build; off, cards wait for the owner's Serve or Build. A session starts a card run only to carry out the owner's words, quoting them with `build <key> --asked` ([0124](docs/adr/0124-only-the-owner-or-auto-build-starts-a-card-run.md)). Main always builds after every merge. The hub runs a nonoverlapping tick every 15 seconds and fetches other boards' origin branches on each GitHub polling slot. The Settings toggle saves immediately; `settings set auto-build on|off` sets it through the CLI.
316
- _Avoid_: auto-serve, build rule
348
+ **Auto serve**:
349
+ The board's `auto_build` setting (the key keeps its name), labelled "Auto serve" in Settings, off by default. On, each card with commits beyond main builds or serves after each new head, and cards show no Serve; off, cards wait for the owner's Serve. A session starts a card run only to carry out the owner's words, quoting them with `build <key> --asked` ([only the owner or Auto serve starts a card run](docs/adr/2026-11-02-1806-only-the-owner-or-auto-build-starts-a-card-run.md)). Main always builds after every merge. The hub runs a nonoverlapping tick every 15 seconds and fetches other boards' origin branches on each check. The Settings toggle saves immediately; `settings set auto-build on|off` sets it through the CLI.
350
+ _Avoid_: Auto-build, build rule
317
351
 
318
352
  **Implement**:
319
- The orange Implement last in the open card's workflow row, on a work card still unstarted in Todo, held or not, blocked or not, that has no **Action needed**: the card's `buildable` from `board/domain.mjs`. Its confirm reads "Implement #92? Claude starts its implementer now with the notes as they stand." Owner-facing words call a card's agent an implementer and its `building` status implementing, so Build, Serve and Install only mean the package of a worktree or main; the code keeps `buildable`, `card-build`, the `building` status and builder records ([0166](docs/adr/0166-a-todo-cards-button-reads-implement.md)). On a blocked card it queues a **queued build**, its confirm "Implement #92 once #53 is done?" ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)). On a held card it reads "Unhold and implement" in its confirm and the board server clears the hold as Unhold does before the start; a held card outside Todo keeps Unhold ([0141](docs/adr/0141-a-held-todo-card-shows-build-in-place-of-unhold.md)). It confirms, sends `card-build {key}` and reads "Starting…" while the board server starts the build: the refusals, the builder pick, the worktree and the building mark that `builder start --kind build --worktree` makes. Started, the card is in In Progress reading **Waiting for orchestrator**, and the server wakes the session with `card-build {key, ref, kind, model, reason, worktree}` (`model` only for claude) to brief and launch the builder. Refused, the card stays in Todo showing **Couldn't start implementing** ([0122](docs/adr/0122-a-todo-card-that-nothing-blocks-has-build.md), [0139](docs/adr/0139-a-build-tap-starts-the-build-in-the-board-server.md)). It isn't an app's Build, which runs the **build script**.
353
+ The orange Implement last in the open card's workflow row, on a work card still unstarted in Todo, held or not, blocked or not, that has no **Action needed**: the card's `buildable` from `board/domain.mjs`. Its confirm reads "Implement #92? Claude starts its implementer now with the notes as they stand." Owner-facing words call a card's agent an implementer and its `building` status implementing, so Build, Serve and Install only mean the package of a worktree or main; the code keeps `buildable`, `card-build`, the `building` status and builder records ([a Todo card's button reads Implement, and Build and Serve only mean the package](docs/adr/2026-11-03-1549-a-todo-cards-button-reads-implement.md)). On a blocked card it queues a **queued build**, its confirm "Implement #92 once #53 is done?" ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)). On a held card it reads "Unhold and implement" in its confirm and the board server clears the hold as Unhold does before the start; a held card outside Todo keeps Unhold ([a held Todo card shows Build in place of Unhold](docs/adr/2026-11-03-0234-a-held-todo-card-shows-build-in-place-of-unhold.md)). It confirms, sends `card-build {key}` and reads "Starting…" while the board server starts the build: the refusals, the builder pick, the worktree and the building mark that `builder start --kind build --worktree` makes. Started, the card is in In Progress reading "starting" until its implementer's first status line, its Next cleared, and the server launches the builder itself, Claude or Codex, from the card's notes, with the thread line "Builder launched on <model> in <worktree>." linking its log; no event wakes the session ([the hub launches every agent from the card](docs/adr/2026-11-04-2130-the-hub-launches-every-agent-from-the-card.md)). A launch that fails puts the card back in Todo showing **Couldn't start implementing**. Refused, the card stays in Todo showing **Couldn't start implementing** ([a Todo card that nothing blocks has Build](docs/adr/2026-11-02-1745-a-todo-card-that-nothing-blocks-has-build.md), [a Build tap starts the build in the board server](docs/adr/2026-11-03-0219-a-build-tap-starts-the-build-in-the-board-server.md), [a card reads starting from its tap, with one dispatched mark](docs/adr/2026-11-03-1718-a-card-reads-starting-from-its-tap-with-one-dispatched-mark.md)). It isn't an app's Build, which runs the **build script**.
320
354
  _Avoid_: card Build, go button, start button
321
355
 
356
+ **Queued section**:
357
+ The one section at the top of Todo that holds the cards waiting for an **implementer slot**: each **Queued build**, and while **Auto-pull** is on every pullable card, ready ones waiting over the cap included. Bumped cards lead it, the latest bump on top; the rest follow oldest first, by the tap's time or else when the card was made, so a card's unbump returns it to that place. Whenever In Progress is under Maximum parallel implementers the board server takes the queue from its top: it starts a Queued build nothing blocks, and starts and launches the build of a ready card. Queued cards take no slot ([In Progress has a Queued section, and the pull takes its top under the cap](docs/adr/2026-11-04-0121-in-progress-has-a-queued-section.md); [Queued sits at the top of Todo](docs/adr/2026-11-04-0150-queued-sits-at-the-top-of-todo.md)).
358
+ _Avoid_: backlog, waiting lane
359
+
322
360
  **Queued build**:
323
- An Implement the owner tapped on a card an unfinished dep blocks: `queued_at` on its wave entry, with no builder record or worktree, and the thread line "Implement queued: it starts once #53 is done." The card sits in In Progress, its time line reading "blocked by #53" in place of a builder line, and once nothing holds or blocks it the board server starts the build as the tap would, from the newest main, waking the session with `card-build`. `item set` prints `queued build starts: <key>` for it and sends no `card-unblocked`. A start that is refused or fails sends the card back to Todo with **Couldn't start implementing** ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)).
361
+ An Implement the owner tapped on a card an unfinished dep blocks: `queued_at` on its wave entry, with no builder record or worktree, and the thread line "Implement queued: it starts once #53 is done." The card sits in Todo's **Queued section**, its time line reading "blocked by #53" in place of a builder line, and once nothing holds or blocks it and it reaches the queue's top with an **implementer slot** free the board server starts the build as the tap would, from the newest main, and launches its builder. `item set` prints `queued build starts: <key>` for it and sends no `card-unblocked`. A start that is refused or fails sends the card back to Todo with **Couldn't start implementing** ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)).
324
362
  _Avoid_: pending build, waiting build
325
363
 
326
- **Waiting for orchestrator**:
327
- A card's builder line while the builder record the owner's Implement tap made is still `tapped`: the board started the build, and the session hasn't launched its builder. The builder's own `builder start` takes the record up, and its first status line replaces it. It is never a builder status line and isn't written to the thread ([0139](docs/adr/0139-a-build-tap-starts-the-build-in-the-board-server.md)).
328
- _Avoid_: queued, pending build
329
-
330
364
  **Couldn't start implementing**:
331
- The thread line, of kind `build-refused`, the board server writes when it refuses an Implement tap, with the reason in the owner's words: paused, or a noted prototype pick that waits on its confirm, or why a **queued build** couldn't start. The Todo card shows it in its status line while it is the card's newest line other than a status line ([0139](docs/adr/0139-a-build-tap-starts-the-build-in-the-board-server.md)).
365
+ The thread line, of kind `build-refused`, the board server writes when it refuses an Implement tap, with the reason in the owner's words: paused, or a noted prototype pick that waits on its confirm, or why a **queued build** couldn't start, or a builder launch that failed ("the launch failed (<reason>). Tap Implement to try again."). The Todo card shows it in its status line while it is the card's newest line other than a status line ([a Build tap starts the build in the board server](docs/adr/2026-11-03-0219-a-build-tap-starts-the-build-in-the-board-server.md)).
332
366
  _Avoid_: Couldn't start the build, build error, failed start
333
367
 
334
368
  **Auto-pull**:
335
- The board's `auto_pull` setting, off by default, which reads "Pull in Todo cards when idle" in Board settings' Todo section and turns on or off with no confirmation. On, while the board is idle (no builder runs and nothing waits in Orchestrator review), the board server's minute check sends `card-pull {key}` for the top **pullable** card, Ready cards first, then cards with no state, each in board order ([0170](docs/adr/0170-the-idle-pull-takes-ready-cards-first.md)): an unstarted Todo work card that nothing blocks or holds, with no questions, no grill under way and no message a session is working on ([0138](docs/adr/0138-a-card-moves-to-in-progress-only-once-building-starts.md)). A running build keeps the board from being idle; a running grill or prototype does not ([0167](docs/adr/0167-planners-and-implementers-are-two-kinds-of-agent.md)). New cards are never pulled, nor a card from an ask still New, grilling or prototyping; a Ready one is ([0154](docs/adr/0154-a-new-card-is-ready-grilling-or-prototyping.md)). It writes "Pulled in: the board was idle." in the card's thread, and pulls the next only once that card stops being pullable. The session takes the card's next step: a grill when its notes leave something open, else a build ([0123](docs/adr/0123-an-idle-board-pulls-in-its-top-todo-card.md)). With nothing pullable it sends `card-plan {key}` instead, one at a time, for the top Todo card not set Ready that isn't held, owes or awaits no answer and has no planner running, while no card is being grilled or prototyped; the session starts a grill, or a prototype for UI work, on it.
369
+ The board's `auto_pull` setting, off by default, which reads "Auto implement Todo cards" in Board settings' Auto section and turns on or off with no confirmation. On, the board server starts and launches the build of the top **pullable** cards in board order, one per **implementer slot** free, on every board change and at start ([auto implement fills In Progress up to Maximum parallel implementers, on every board change](docs/adr/2026-11-04-0057-auto-implement-fills-in-progress-up-to-a-cap.md)): a pullable card is a Ready, unstarted work card that nothing blocks or holds, with no question open or waiting on Claude, no grill under way and no message a session is working on, which waits in the **Queued section** while the switch is on ([the idle pull takes ready cards first, and plans the top card when none is ready](docs/adr/2026-11-03-1631-the-idle-pull-takes-ready-cards-first.md), [a card moves to In Progress only once building starts](docs/adr/2026-11-03-0202-a-card-moves-to-in-progress-only-once-building-starts.md)). The slots are the board's **Maximum parallel implementers** (`max_implementers`, 10 by default, the number beside the switch), less the cards with a running build or waiting in Orchestrator review, less the pulled cards whose build hasn't started; a running grill or prototype and a card waiting on the owner take none ([planners and implementers are two kinds of agent](docs/adr/2026-11-03-1551-planners-and-implementers-are-two-kinds-of-agent.md)). New cards are never pulled, nor a card from an ask still New, grilling or prototyping; a Ready one is ([a new card is ready, grilling or prototyping, and reads ready in green when it is](docs/adr/2026-11-03-0516-a-new-card-is-ready-grilling-or-prototyping.md)). It writes "Pulled in: an implementer slot was free." in the card's thread ([an idle board pulls in its top Todo card](docs/adr/2026-11-02-1754-an-idle-board-pulls-in-its-top-todo-card.md)). While the board is idle (no build running and nothing in Orchestrator review) with nothing pullable, it launches a planner instead, one at a time, on the top Todo card not set Ready that isn't held, owes or awaits no answer and has no planner running, while no card is being grilled or prototyped: a prototype when the card is prototyping, else a grill ([the hub launches every agent from the card](docs/adr/2026-11-04-2130-the-hub-launches-every-agent-from-the-card.md)).
336
370
  _Avoid_: auto-start, idle pickup
337
371
 
338
372
  **Auto-triage**:
339
- The board's `auto_triage` setting, off by default, which reads "Triage Todo when idle" in Board settings' Todo section and turns on or off with no confirmation. On, while the board is idle as for **Auto-pull** and Todo changed since the last triage, at most once a host day and before any pull, the board server declares topic `todo-triage-<date>` ("Todo triage <date>") and sends `todo-triage {date, topic}`. The session looks for duplicates, cards a newer card covers, cards ready to close and stale deps: it links and merges clear duplicates itself, asks one question per other finding on that topic, and replies to the event, which lets the pull go ([0165](docs/adr/0165-an-idle-board-triages-its-todo-once-a-day.md)).
373
+ The board's `auto_triage` setting, off by default, which reads "Triage overnight" in Board settings' Auto section and turns on or off with no confirmation. On, once a night from the middle of the hub's quiet hours (03:00 by default) to their end, when two or more cards wait on open questions, nothing builds, usage isn't paused and something changed since the last triage, the board server declares topic `overnight-triage-<date>` ("Overnight triage <date>") and sends `overnight-triage {date, topic, cards}` before any pull. The session merges overlapping questions onto the newest of their cards, resolving the others "Replaced by" it and copying the owner's answer onto each card once it lands; merges duplicate cards; and does the Todo hygiene over the Todo and Stale cards, never Done: duplicates, cards a newer card covers, cards ready to close and stale deps. It asks one question per finding it can't settle on that topic, held until morning by quiet hours, and replies to the event, which lets the pull go ([triage runs once overnight on cards waiting on your answers](docs/adr/2026-11-04-1900-triage-runs-once-overnight-on-cards-waiting-on-your-answers.md)).
340
374
  _Avoid_: cleanup, grooming
341
375
 
376
+ **Auto review**:
377
+ The board's `auto_review` setting, off by default, whose helper in Board settings' Auto section says it may use a lot of usage. On, the hub's poll lists the repo's open PRs from others that touch a file one of the board's cards changed, or that ask the owner for review, in `data/incoming.json`, and while the board is idle as for **Auto-pull** the board server sends `pr-review` for one at a time. The session posts one Comment review per PR head under the owner's login, adding only new points, or holds it for the owner when it finds a blocker, disagrees with a card's decision or clashes with a card in progress, and records it with `review record`. The board's "Auto Review" lane shows each PR as needs you, reviewing or posted, older posted ones under "Posted earlier"; a held one is also in Needs you and pushes ([each board reviews incoming PRs that touch its work, in an Auto Review lane](docs/adr/2026-11-03-1731-each-board-reviews-incoming-prs-that-touch-its-work.md)).
378
+ _Avoid_: review mesh, PR watcher
379
+
380
+ **Idle notification**:
381
+ The board's `idle_notification` setting, off by default, which reads "Idle notification" in Board settings' Auto section and turns on or off with no confirmation. On, once the board has been strictly idle for 15 minutes (no agent running, no grill or prototype under way, nothing in Orchestrator review, no pulled card waiting and no event a session is working on), the board server pushes "<board> has gone idle" once, with the cards landed and waves finished since the last idle push; it pushes again only after the board has been busy and idle again ([an idle board pushes once when it has gone idle](docs/adr/2026-11-04-0257-an-idle-board-pushes-once-when-it-has-gone-idle.md)).
382
+ _Avoid_: idle reminder, armed reminder
383
+
342
384
  **Notes**:
343
- The owning session's understanding of a work item so far: what was asked, what is settled, what is open. A Markdown file in its wave's folder that the item names in `plan` (`item set --notes-file`), rewritten as the grill settles things, or with no file the item's short `notes` text. "Notes ↗" opens them as a page sized for the phone, first on the open card's final details line before Install and Review on GitHub; the board keeps no summary of them and a card with no notes omits the link. The thread keeps the short news ([0053](docs/adr/0053-notes-replace-the-full-plan-and-cards-start-on-their-own.md), [0062](docs/adr/0062-notes-is-a-link-in-the-details-list.md), [0067](docs/adr/0067-a-cards-external-links-share-the-last-details-line.md)).
385
+ The owning session's understanding of a work item so far: what was asked, what is settled, what is open. A Markdown file in its wave's folder that the item names in `plan` (`item set --notes-file`), rewritten as the grill settles things, or with no file the item's short `notes` text. "Notes ↗" opens them as a page sized for the phone, first on the open card's final details line before Install and Review on GitHub; the board keeps no summary of them and a card with no notes omits the link. The thread keeps the short news ([notes replace the full plan, and a card starts on its own](docs/adr/2026-10-29-1816-notes-replace-the-full-plan-and-cards-start-on-their-own.md), [notes is a link in the details list, with no stored summary](docs/adr/2026-10-30-1626-notes-is-a-link-in-the-details-list.md), [a card's external links share the last details line](docs/adr/2026-10-30-2008-a-cards-external-links-share-the-last-details-line.md)).
344
386
  _Avoid_: full plan, plan, spec
345
387
 
346
388
  **Held**:
347
- A work card the owner paused with its Hold button, which opens the shared duration picker: Forever, until the owner taps Unhold, or until a time, its **pick-up time**. Hold and Unhold apply on the board at once, and the board server writes them to the wave file with the owner's thread line ([0131](docs/adr/0131-the-cli-and-board-server-do-the-boards-housekeeping.md)). It doesn't start, and the session stops work on a running one, until it is resumed (a held Todo card's Build resumes and starts it, [0141](docs/adr/0141-a-held-todo-card-shows-build-in-place-of-unhold.md)) ([0106](docs/adr/0106-the-board-applies-the-owners-hold-resume-and-done-at-once.md)). The card's last line reads "held" or "held until Wed 9:00 am" after its time. A card that leaves Todo is never still held: any write that takes it out (`item set --status building`, `fixing`, `checking`, `done`, `merged` or `dropped`, `--pr`, `--pushed`) clears the hold and its pick-up time, and the board shows held only on a Todo card. Every other action-row button, Unhold included, asks to confirm first, through `B.confirm` (`dialogs.js`).
389
+ A work card the owner paused with its Hold button, which opens the shared duration picker: Forever, until the owner taps Unhold, or until a time, its **pick-up time**. Hold and Unhold apply on the board at once, and the board server writes them to the wave file with the owner's thread line ([the CLI and board server do the board's housekeeping](docs/adr/2026-11-02-2044-the-cli-and-board-server-do-the-boards-housekeeping.md)). It doesn't start, and the session stops work on a running one, until it is resumed (a held Todo card's Build resumes and starts it, [a held Todo card shows Build in place of Unhold](docs/adr/2026-11-03-0234-a-held-todo-card-shows-build-in-place-of-unhold.md)) ([the board applies the owner's Hold, Resume and Done at once](docs/adr/2026-11-02-0009-the-board-applies-the-owners-hold-resume-and-done-at-once.md)). The card's last line reads "held" or "held until Wed 9:00 am" after its time. A card that leaves Todo is never still held: any write that takes it out (`item set --status building`, `fixing`, `checking`, `done`, `merged` or `dropped`, `--pr`, `--pushed`) clears the hold and its pick-up time, and the board shows held only on a Todo card. Every other action-row button, Unhold included, asks to confirm first, through `B.confirm` (`dialogs.js`).
348
390
  _Avoid_: paused, frozen, on hold (as a status name)
349
391
 
350
392
  **Pick-up time**:
351
- When a card held until a time resumes itself: `pick_up_at` in its wave file (`board.mjs item set --pick-up-at`), or the `until` of the owner's newer `card-hold`. Within a minute of it the board server resumes the card, writes a thread line, and sends `card-unblocked {key, until}` unless a dep is unfinished, so it starts on its own once nothing else blocks it ([0118](docs/adr/0118-a-card-can-be-held-until-a-time.md)). A bump doesn't skip it; resume the card or change the time to start early. It is separate from a Linear due date.
393
+ When a card held until a time resumes itself: `pick_up_at` in its wave file (`board.mjs item set --pick-up-at`), or the `until` of the owner's newer `card-hold`. Within a minute of it the board server resumes the card, writes a thread line, and sends `card-unblocked {key, until}` unless a dep is unfinished, so it starts on its own once nothing else blocks it ([a card can be held until a time](docs/adr/2026-11-02-1727-a-card-can-be-held-until-a-time.md)). A bump doesn't skip it; resume the card or change the time to start early. It is separate from a Linear due date.
352
394
  _Avoid_: due date, reminder, snooze (for a card)
353
395
 
354
396
  **Builder**:
355
- An agent (Claude Opus, Claude Sonnet, Codex…) working on a work item, which owner-facing words call an implementer ([0166](docs/adr/0166-a-todo-cards-button-reads-implement.md)), with one builder record each (`board.mjs builder … --agent <name>`; the first is `main`). The record holds its label, kind (claude or codex; a record written as opus or sonnet reads as claude with that model), model (opus or sonnet for claude, set by `builder start --model`, which prints "model: Claude Sonnet"), start, ETA and finish, not its progress. Each progress line (`builder progress --phase <phase> "<detail>"`, which needs `--site`) goes only to the card's thread, as a **status line**: a phase, Reading, Building, Testing, Checking or Landing, and a detail of at most 80 characters, refused when longer ("Testing: fix for the scroll jump"; another agent's reads "Codex testing: …"), shown as one line with no bubble. Status lines written before phases stay as written ([0137](docs/adr/0137-a-builder-status-line-is-a-phase-and-a-short-detail.md)). The card's status line under its title is the thread's newest status line since its earliest running agent started, its phase first ("Testing · fix for the scroll jump · 3m ago"), or "Starting" before the first, with its age, behind a pulsing dot as Orchestrator review and Working on it have, and, once a status line has a phase, five bars at the end of the card's time row, after its unread count, finished phases filled and the current one pulsing, only on an In Progress card while a builder runs ([0160](docs/adr/0160-a-building-cards-phase-bars-end-its-time-row.md)), and an optional "ETA about 4:30 pm" line under that (owner ask on INT-76). In the thread every implementer's status line stays orange, dot included, whether its agent is working or done (owner, card INT-77). `builder done` marks the record done and keeps it; closing the card’s last open builder record clears its building or fixing status. Linking a PR clears either status too. The thread shows each record as **agent lines** among its messages, with no bubble: "Claude Opus implementer started" (or "Claude Sonnet implementer", "Codex implementer"; the model, not the label, names it, a label's builder reading implementer) at its start, always orange and with its ETA while the agent runs, and "Claude Opus implementer finished" at its finish, the only green one (owner, question `int42-agents-look`, option C; owner ask on INT-63). The session's own thread summary closes the work. A builder is a **planner** or an **implementer**: planners are the grill and prototype agents, which write no output code; every other kind is an implementer. A planner's model defaults to Sonnet for a prototype and Opus for a grill ("Claude Sonnet prototype started"); its status and started lines are the owner's blue (`--accent`, the one human blue, [0169](docs/adr/0169-one-human-blue.md)), on a Todo card too, never with phase bars; while a build runs, the build's line wins on the card; and a running planner leaves the board idle for the idle pull ([0167](docs/adr/0167-planners-and-implementers-are-two-kinds-of-agent.md)). The kind words are for code and ADRs; the screen says what each agent does.
397
+ An agent (Claude Opus, Claude Sonnet, Codex…) working on a work item, which owner-facing words call an implementer ([a Todo card's button reads Implement, and Build and Serve only mean the package](docs/adr/2026-11-03-1549-a-todo-cards-button-reads-implement.md)), with one builder record each (`board.mjs builder … --agent <name>`; the first is `main`). The record holds its label, kind (claude or codex; a record written as opus or sonnet reads as claude with that model), model (opus or sonnet for claude, set by `builder start --model`, which prints "model: Claude Sonnet"), start, ETA and finish, not its progress. Each progress line (`builder progress --phase <phase> "<detail>"`, which needs `--site`) goes only to the card's thread, as a **status line**: a phase, Reading, Building, Testing, Checking or Landing, and a detail of at most 80 characters, refused when longer ("Testing: fix for the scroll jump"; another agent's reads "Codex testing: …"), shown as one line with no bubble. Status lines written before phases stay as written ([a builder status line is a phase and a short detail](docs/adr/2026-11-03-0128-a-builder-status-line-is-a-phase-and-a-short-detail.md)). The card's status line under its title is the thread's newest status line since its earliest running agent started, its phase first ("Testing · fix for the scroll jump · 3m ago"), or "Starting" before the first, with its age, behind a pulsing dot as Orchestrator review and Working on it have, and, once a status line has a phase, five bars at the end of the card's time row, after its unread count, finished phases filled and the current one pulsing, only on an In Progress card while a builder runs ([a building card's phase bars end its time row](docs/adr/2026-11-03-1519-a-building-cards-phase-bars-end-its-time-row.md)), and an optional "ETA about 4:30 pm" line under that (owner ask on INT-76). In the thread every implementer's status line stays orange, dot included, whether its agent is working or done (owner, card INT-77). `builder done` marks the record done and keeps it; closing the card’s last open builder record clears its building or fixing status. Linking a PR clears either status too. The thread shows each record as **agent lines** among its messages, with no bubble: "Claude Opus implementer started" (or "Claude Sonnet implementer", "Codex implementer"; the model, not the label, names it, a label's builder reading implementer) at its start, always orange and with its ETA while the agent runs, and "Claude Opus implementer finished" at its finish, the only green one (owner, question `int42-agents-look`, option C; owner ask on INT-63). The session's own thread summary closes the work. A builder is a **planner** or an **implementer**: planners are the grill and prototype agents, which write no output code; every other kind is an implementer. A planner's model defaults to Sonnet for a prototype and Opus for a grill ("Claude Sonnet prototype started"); its status and started lines are the owner's blue (`--accent`, the one human blue, [one human blue](docs/adr/2026-11-03-1627-one-human-blue.md)), on a Todo card too, never with phase bars; while a build runs, the build's line wins on the card; and a running planner takes no implementer slot and leaves the board idle ([planners and implementers are two kinds of agent](docs/adr/2026-11-03-1551-planners-and-implementers-are-two-kinds-of-agent.md)). The kind words are for code and ADRs; the screen says what each agent does.
356
398
  _Avoid_: worker, bot
357
399
 
358
400
  **Dispatched record**:
359
- A builder record the session opens with `builder start --dispatch` right before it launches an agent of any kind (build, prototype, grill), so the card's builder line reads "Starting" from the launch and not from the agent's own start. The agent's own `builder start` takes it up as it does a `tapped` record: the kind, a Claude model and the worktree stay, the record starts again at now and is no longer dispatched. The session never posts "a builder is working" itself ([0152](docs/adr/0152-the-session-opens-the-builder-record-when-it-dispatches-an-agent.md)).
360
- _Avoid_: pre-start, placeholder record
401
+ A builder record open before its agent runs, marked with who opened it: `dispatched: 'tap'` when the owner's Implement tap (or a queued build's start) opened it, `dispatched: 'hub'` when the board server opened it to launch a pulled build or a planner (a grill or a prototype) itself, `dispatched: 'session'` when the session ran `builder start --dispatch` right before it launches some other agent. Either way the card's builder line reads "starting" from then until the agent's first status line. The agent's own `builder start` takes it up: the kind, a Claude model and the worktree stay, the record starts again at now and is no longer dispatched. A `--dispatch` on a record the tap opened changes nothing and prints "already open"; a `builder start --agent <other name>` refuses while the tap's main record is open and not taken up. The session never posts "a builder is working" itself ([the session opens the builder record when it dispatches an agent](docs/adr/2026-11-03-0513-the-session-opens-the-builder-record-when-it-dispatches-an-agent.md), [a card reads starting from its tap, with one dispatched mark](docs/adr/2026-11-03-1718-a-card-reads-starting-from-its-tap-with-one-dispatched-mark.md)).
361
402
 
362
403
  **Judgment call**:
363
- A decision a builder makes that its brief didn't settle, recorded on its builder record as it makes it (`builder call <key> "<call>"`, one plain line), or a "Question: …" it asks the session before building. The thread shows a record's calls as one collapsed entry under its agent lines. The session checks them against the owner's words and the other cards and marks the record **verified** (`builder verified`); `land` refuses while a record on the card has a call after that mark. A builder start on a record with unverified calls resumes that build, calls and worktree kept ([0155](docs/adr/0155-a-builder-records-its-judgment-calls-and-the-session-verifies-them.md)).
404
+ A decision a builder makes that its brief didn't settle, recorded on its builder record as it makes it (`builder call <key> "<call>"`, one plain line), or a "Question: …" it asks the session before building. The thread shows a record's calls as one collapsed entry under its agent lines. The session checks them against the owner's words and the other cards and marks the record **verified** (`builder verified`), which finishes a handed-back build in the same step; finishing refuses while a record on the card has a call after that mark. A builder start on a record with unverified calls resumes that build, calls and worktree kept ([a builder records its judgment calls and the session verifies them before land](docs/adr/2026-11-03-0514-a-builder-records-its-judgment-calls-and-the-session-verifies-them.md)).
364
405
  _Avoid_: guess, assumption, decision log
365
406
 
407
+ **Builder ask**:
408
+ A question a running builder puts to the board's session, the **orchestrator**, at any point mid-build (`builder ask <key> "<question>"`, id `ask<n>`), carrying on while it waits. It shows in the card's thread as a normal message named by the builder's model, "Claude Opus builder", and wakes the session with `builder-ask {key, ask, agent, text}`. The session answers it (`builder answer`) or, when it isn't confident or wants the owner's opinion, defers it (`builder defer`); both show as "Orchestrator", the name the thread gives every line the session writes. The card stays quiet meanwhile: neither line is unread, pushed, nor answers an owner message. A deferred ask is a "Question:" **judgment call**, and the session's review puts it to the owner as a card question naming the ask, after its other checks and before a draft PR or In Review; `builder verified` refuses until it has. A card whose only open questions are deferred asks waits on the owner from In Progress with Open questions, its new questions one unread message on the card and one "N new questions" line in its thread, and no **Action needed** ([a builder asks the orchestrator mid-build, and only what it defers reaches the owner](docs/adr/2026-11-04-0247-a-builder-asks-the-orchestrator-mid-build.md)). The owner never answers a builder mid-build.
409
+ _Avoid_: builder question, check-in
410
+
366
411
  **Stalled**:
367
- A builder still recorded as running whose last progress, or start before its first progress, was at least 30 minutes ago. Its card carries a red Stalled button until fresh progress or completion; silence calls for a check, without establishing that the process has failed.
412
+ A builder still recorded as running whose last progress, or start before its first progress, was at least 30 minutes ago. Its card's status line turns the needs-you red, and a tap on it nudges Claude, until fresh progress or completion; silence calls for a check, without establishing that the process has failed.
368
413
  _Avoid_: stuck, hung, failed
369
414
 
370
415
  **Worktree**:
371
- The git worktree a builder works in, never the folder the session, a running app or the hub uses. A board's is `~/.claude/kickflip/worktrees/<card id>` on branch `<card id>` from its chosen repo branch, or from local main for a **local board**, of the board's own folder, the hub board's included (`hub/board-repo.mjs` decides which), made by `board.mjs builder start --worktree` and kept on the builder record; the owning session checks and commits there, then **lands** it (`board.mjs land`): rebased onto main, tested, fast-forwarded into the live folder's main, the hub or board servers restarted, the worktree and branch removed. A repo card's comes from wave-build ([0064](docs/adr/0064-every-builder-works-in-a-worktree.md)).
416
+ The git worktree a builder works in, never the folder the session, a running app or the hub uses. A board's is `~/.claude/kickflip/worktrees/<card id>` on branch `<card id>` from its chosen repo branch, or from the local copy of its recorded default branch for a **local board** ([a local board builds and lands on its default branch](docs/adr/2026-11-03-1851-a-local-board-builds-and-lands-on-its-default-branch.md)), of the board's own folder, the hub board's included (`hub/board-repo.mjs` decides which), made by a build's `board.mjs builder start` (or `--worktree`, or the Implement tap) and kept on the builder record; the builder checks and commits there, and **finishing** the card (its `builder done --text`, the session's `builder verified`, or `board.mjs land`) **lands** it: rebased onto that branch, refused if it adds an ADR named with a number instead of a timestamp, tested, fast-forwarded into the live folder's copy of it, the hub or board servers restarted, the worktree and branch removed, and with the board's "Push main after a land" switch on, the branch pushed to origin. On a GitHub board finishing pushes the card's branch and opens a draft PR instead, and on a plain git remote pushes the branch. A repo card's comes from wave-build ([every builder works in a worktree, and the hub's own fault shows once](docs/adr/2026-10-30-1654-every-builder-works-in-a-worktree.md)).
372
417
  _Avoid_: copy, checkout, live folder (for the builder's)
373
418
 
374
419
  ### Talking with the owner
375
420
 
376
421
  **New task**:
377
- A free-form request or question the owner sends from the board's + button (or by pressing n twice). Code and events call it an **ask**: an `ask` event whose thread is `ask:<event id>`. It is a **New card** at the top of Todo, with no wave and no Action needed, until Claude sorts it one of three ways ([0047](docs/adr/0047-the-plus-makes-a-new-card.md)): files it under a wave as a work item, whose thread opens with it (`item set --from-ask`), and sets its **card state**; folds it into the card it's about, whose thread then holds the message marked Moved (`item relate-ask`, undone by `ask unfold`); or answers it, which puts it in the Asks lane below Done, named by when it was asked, whose thread takes the owner's later replies ([0144](docs/adr/0144-answered-asks-have-their-own-section-below-done.md)). An answer that leaves a question open on it keeps it in Todo with Action needed, never in Asks, until the owner answers and Claude replies, or it is closed; it stays in Todo while Claude takes up the answer ([0059](docs/adr/0059-an-unstarted-card-waits-on-its-questions-in-todo.md)). When another board fits it better, the owner can have it **moved there** (`ask move`): it becomes a New card on that board reading "Moved from <this board>", and here a Done card whose thread links to it. Folding is within one board; a move is between boards. An answer that waits on the owner, such as a choice only the owner can settle, keeps it in In Review with Action needed until the owner taps Mark as done or the Done in its thread ([0035](docs/adr/0035-an-ask-can-wait-in-progress-until-the-owner-marks-it-done.md)).
422
+ A free-form request or question the owner sends from the board's + button (or by pressing n twice). Code and events call it an **ask**: an `ask` event whose thread is `ask:<event id>`. It is a **New card** at the top of Todo, with no wave and no Action needed, until Claude sorts it one of three ways ([the + makes a New card, which Claude files, folds or answers](docs/adr/2026-10-29-1639-the-plus-makes-a-new-card.md)): files it under a wave as a work item, whose thread opens with it (`item set --from-ask`), and sets its **card state**; folds it into the card it's about, whose thread then holds the message marked Moved (`item relate-ask`, undone by `ask unfold`); or answers it, which puts it in the Asks lane below Done, named by when it was asked, whose thread takes the owner's later replies ([answered asks have their own section below Done, and Done and Asks show 10 cards at a time](docs/adr/2026-11-03-0259-answered-asks-have-their-own-section-below-done.md)). An answer that leaves a question open on it keeps it in Todo with Action needed, never in Asks, until the owner answers and Claude replies, or it is closed; it stays in Todo while Claude takes up the answer ([an unstarted card waits on its questions in Todo, and its one action button follows what it waits on](docs/adr/2026-10-30-1309-an-unstarted-card-waits-on-its-questions-in-todo.md)). When another board fits it better, the owner can have it **moved there** (`ask move`): it becomes a New card on that board reading "Moved from <this board>", and here a Done card whose thread links to it. Folding is within one board; a move is between boards. An answer that waits on the owner, such as a choice only the owner can settle, keeps it in In Review with Action needed until the owner taps Mark as done or the Done in its thread ([an ask can wait on the owner before Done, and the owner closes any open card from its thread](docs/adr/2026-10-29-1639-an-ask-can-wait-in-progress-until-the-owner-marks-it-done.md)).
378
423
  _Avoid_: ask (in what the owner reads), message, prompt, Waiting for Claude strip
379
424
 
380
425
  **Thread**:
381
- The conversation on one work item: Claude's reports, builders' status lines, the owner's messages, mirrored GitHub comments, and answers to the item's questions. On a card not in Done, its reply form has a Done, left of Send, that closes the card ([0035](docs/adr/0035-an-ask-can-wait-in-progress-until-the-owner-marks-it-done.md)).
426
+ The conversation on one work item: Claude's reports, builders' status lines, the owner's messages, mirrored GitHub comments, and answers to the item's questions. On a card not in Done, its reply form has a Done, left of Send, that closes the card ([an ask can wait on the owner before Done, and the owner closes any open card from its thread](docs/adr/2026-10-29-1639-an-ask-can-wait-in-progress-until-the-owner-marks-it-done.md)).
382
427
  An open card shows its thread's newest 3 messages as it opens, or from its oldest **unread message** when more than 3 messages follow it, at most 10, unread as of when the card opened. Messages that arrive while it is open add below, hiding none. Messages are the owner's, Claude's (replies included) and other people's; builder, status and ask-link lines show among the messages they sit between and don't count. "Show more · N previous messages" at the top adds the next 3 older messages each tap and goes when nothing older is left. The expansion lasts while the card stays open, through repaints and new messages, and closing the card puts it back to 3. A message being edited always shows, with every line after it; one waiting on Claude shows only where the window reaches it.
383
- An owner message Claude hasn't answered yet ends with **Waiting for Claude…**, or Working on it while Claude is on it. An answer to a question stops waiting once it's acted on: its question resolved after it, a later prototype round on it, or a build started on the card after it ([0157](docs/adr/0157-an-answer-stops-waiting-once-its-acted-on.md)). A batch of the owner's answers in a row in the same state carries it once, under the last answer.
428
+ An owner message Claude hasn't answered yet ends with **Waiting for Claude…**, or Working on it while Claude is on it. An answer to a question stops waiting once it's acted on: its question resolved after it, a later prototype round on it, or a build started on the card after it ([an answer stops waiting once it's acted on, and a Next set during the card's questions clears](docs/adr/2026-11-03-1313-an-answer-stops-waiting-once-its-acted-on.md)). A batch of the owner's answers in a row in the same state carries it once, under the last answer.
384
429
  _Avoid_: comments, chat
385
430
 
386
431
  **Unread message**:
@@ -388,35 +433,39 @@ A message in a card's thread from Claude (replies included) or GitHub, newer tha
388
433
  _Avoid_: inbox, notification. "New" names it only in that count's "N new messages"; a New card is an unsorted ask.
389
434
 
390
435
  **Last visit**:
391
- The board and threads this device last showed, kept in its browser storage. The next visit paints it dimmed at first paint, readable at any age, with the controls that send held until the fresh board lands and replaces it in place, flashing a fading blue border round each lane count, Needs you line or thread message that changed ([0028](docs/adr/0028-the-board-opens-on-the-last-visit.md)); a card that changed shows its own sign ([0135](docs/adr/0135-an-updated-card-takes-a-brief-tint.md)). A board the app shell left fresh and comes back to with no change since paints it live instead ([0055](docs/adr/0055-one-app-for-the-whole-hub.md)). It paints only under the build that saved it, a hash of the shell's file versions (`hub/shell.mjs` `shellHtml`), so code that changed since never reads it; the page then waits for the fresh board. In code it is the snapshot.
436
+ The board and threads this device last showed, kept in its browser storage. The next visit paints it dimmed at first paint, readable at any age, with the controls that send held until the fresh board lands and replaces it in place, flashing a fading blue border round each lane count, Needs you line or thread message that changed ([the board opens on the last visit](docs/adr/2026-10-29-1639-the-board-opens-on-the-last-visit.md)); a card that changed shows its own sign ([an updated card takes a brief tint](docs/adr/2026-11-02-2354-an-updated-card-takes-a-brief-tint.md)). A board the app shell left fresh and comes back to with no change since paints it live instead ([one app for the whole hub](docs/adr/2026-10-29-2005-one-app-for-the-whole-hub.md)). It paints only under the build that saved it, a hash of the shell's file versions (`hub/shell.mjs` `shellHtml`), so code that changed since never reads it; the page then waits for the fresh board. In code it is the snapshot.
392
437
  _Avoid_: cache, offline copy, stale board
393
438
 
394
439
  **Answer banner**:
395
- The one line at the top of a board, above Needs you, naming new tasks Claude answered without making work whose answer this browser hasn't seen: "1 answer · <ask>" or "2 answers · <newest> and 1 more". A tap opens the newest one's card; ✕ hides it on this device until a newer answer. No push goes for an answer ([0006](docs/adr/0006-pushes-only-when-something-waits-on-the-owner.md)).
440
+ The one line at the top of a board, above Needs you, naming new tasks Claude answered without making work whose answer this browser hasn't seen: "1 answer · <ask>" or "2 answers · <newest> and 1 more". A tap opens the newest one's card; ✕ hides it on this device until a newer answer. No push goes for an answer ([a push goes out only when something waits on the owner, on the hub's schedule](docs/adr/2026-10-29-1639-pushes-only-when-something-waits-on-the-owner.md)).
396
441
  _Avoid_: notification, toast
397
442
 
398
443
  **Owner question**:
399
- A multiple-choice question Claude needs the owner to decide, attached to a topic. A builder's judgement call becomes one. One marked **urgent** blocks a build or a merge and shows alone; Claude resolves a question in the step that acts on its answer ([0043](docs/adr/0043-needs-you-gathers-what-waits-and-questions-answer-on-one-page.md)), except an answer with a note and no option, which resolves its question as it arrives ([0114](docs/adr/0114-a-pick-with-no-note-settles-a-prototype-round.md)), and recording a card's close in the wave file resolves each of its questions that has an answer; one with no answer yet stops that write unless forced. The owner's Done still moves the card on the board at once ([0106](docs/adr/0106-the-board-applies-the-owners-hold-resume-and-done-at-once.md)). Adding a question on the same card or setting its notes file resolves answered questions still waiting on Claude; once a card's Action needed is gone, the board server drops its queued push ([0133](docs/adr/0133-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)).
444
+ A multiple-choice question Claude needs the owner to decide, attached to a topic. A builder's judgement call becomes one. One marked **urgent** blocks a build or a merge and shows alone; Claude resolves a question in the step that acts on its answer ([Needs you gathers what waits on the owner, and a topic's questions are answered on one page](docs/adr/2026-10-29-1639-needs-you-gathers-what-waits-and-questions-answer-on-one-page.md)), except an answer with a note and no option, which resolves its question as it arrives ([a pick with no note settles a prototype round](docs/adr/2026-11-02-1607-a-pick-with-no-note-settles-a-prototype-round.md)), and recording a card's close in the wave file resolves each of its questions that has an answer; one with no answer yet stops that write unless forced. The owner's Done still moves the card on the board at once ([the board applies the owner's Hold, Resume and Done at once](docs/adr/2026-11-02-0009-the-board-applies-the-owners-hold-resume-and-done-at-once.md)). Adding a question on the same card or setting its notes file resolves answered questions still waiting on Claude; once a card's Action needed is gone, the board server drops its queued push ([the board records what it knows, and commands make the rule calls](docs/adr/2026-11-03-0003-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)).
400
445
  _Avoid_: poll, decision card
401
446
 
447
+ **Suggested answer**:
448
+ The option of an owner question the overnight triage is confident the owner already chose, from their answer on another card or their long-running context, never from an ADR or CONTEXT.md. The question shows it pre-checked with a green "suggested" chip and the line You answered this on #N: "<answer>", and only the owner's Send answers it ([overnight triage suggests your earlier answers](docs/adr/2026-11-04-2200-overnight-triage-suggests-your-earlier-answers.md)).
449
+ _Avoid_: auto-answer, default, recommendation (the grill's own pick)
450
+
402
451
  **Topic**:
403
452
  The group an owner question belongs to; an item's questions use the topic `item:<wave>/<id>`. A Done card's topic with no open question is resolved, so it never waits on Claude.
404
453
  _Avoid_: category, section
405
454
 
406
455
  **Needs you**:
407
- The orange box at the top of a board listing what waits on the owner, one line per work item, led by the board session's **pending prompts** ([0043](docs/adr/0043-needs-you-gathers-what-waits-and-questions-answer-on-one-page.md)).
456
+ The orange box at the top of a board listing what waits on the owner, one line per work item, led by the board session's **pending prompts** ([Needs you gathers what waits on the owner, and a topic's questions are answered on one page](docs/adr/2026-10-29-1639-needs-you-gathers-what-waits-and-questions-answer-on-one-page.md)).
408
457
  _Avoid_: inbox, digest
409
458
 
410
459
  **Pending prompt**:
411
- A permission prompt or `AskUserQuestion` from a background board session, which its hook hands to the hub and holds the session on until the owner answers in the board's Needs you, or the hub page for a session that owns no board: Allow once, Always allow or Deny, or the question's options. Always allow returns the session rule to Claude Code and keeps that same rule in the hub's `prompts.json`, keyed by session id. The hub remembers rules only with a reliable process start time and binds board rules to the current ownership's `owner.since`; ownership commands clear remembered rules and pending prompts for both the old and new sessions, including boardless entries, even while the hub is stopped. A later exact match on its command, absolute path, domain or bare tool name is allowed immediately, with no push or Needs you line; prefixes and globs never widen a match, and `AskUserQuestion` always asks. Rules end when the session stops or its board's owning session changes, and the hub page lists them read-only under the board. With no answer in 10 minutes the call is denied with a note to ask on the card instead ([0060](docs/adr/0060-background-sessions-prompts-come-to-the-phone.md)).
460
+ A permission prompt or `AskUserQuestion` from a background board session, which its hook hands to the hub and holds the session on until the owner answers in the board's Needs you, or the hub page for a session that owns no board: Allow once, Always allow or Deny, or the question's options. Always allow returns the session rule to Claude Code and keeps that same rule in the hub's `prompts.json`, keyed by session id. The hub remembers rules only with a reliable process start time and binds board rules to the current ownership's `owner.since`; ownership commands clear remembered rules and pending prompts for both the old and new sessions, including boardless entries, even while the hub is stopped. A later exact match on its command, absolute path, domain or bare tool name is allowed immediately, with no push or Needs you line; prefixes and globs never widen a match, and `AskUserQuestion` always asks. Rules end when the session stops or its board's owning session changes, and the hub page lists them read-only under the board. With no answer in 10 minutes the call is denied with a note to ask on the card instead ([a background session's prompts and questions come to the phone](docs/adr/2026-10-30-1516-background-sessions-prompts-come-to-the-phone.md)).
412
461
  _Avoid_: permission request, approval, dialog
413
462
 
414
463
  **Event**:
415
- A signal that wakes the owning session: something the owner did on a page (an ask, an answer, a button), or a board change such as `card-unblocked {key}` when a waiting card’s last unfinished dependency finishes ([0020](docs/adr/0020-cards-wait-on-explicit-blocked-by-links.md)), unless its build is a **queued build**, which the board server starts itself ([0145](docs/adr/0145-build-on-a-blocked-card-queues-it.md)).
464
+ A signal that wakes the owning session: something the owner did on a page (an ask, an answer, a button), or a board change such as `card-unblocked {key}` when a waiting card’s last unfinished dependency finishes ([cards wait on explicit blocked-by links](docs/adr/2026-10-29-1639-cards-wait-on-explicit-blocked-by-links.md)), unless its build is a **queued build**, which the board server starts itself ([Build on a blocked card queues it, and blocked, bumped and Action needed leave the badges](docs/adr/2026-11-03-0301-build-on-a-blocked-card-queues-it.md)).
416
465
  _Avoid_: action, request
417
466
 
418
467
  **Rule**:
419
- A standing instruction from the owner to the sessions that own boards, one line of text kept on Settings. Hub rules apply to every board; each board adds its own on top. The watcher prints both with every wake, and a save wakes each session to say what changes. One Claude codified on the owner's word reads "Added by Claude" ([0039](docs/adr/0039-rules-live-on-settings-at-hub-and-board-level.md)).
468
+ A standing instruction from the owner to the sessions that own boards, one line of text kept on Settings. Hub rules apply to every board; each board adds its own on top. The watcher prints both with every wake, and a save wakes each session to say what changes. One Claude codified on the owner's word reads "Added by Claude" ([rules live on Settings, at hub and board level](docs/adr/2026-10-29-1639-rules-live-on-settings-at-hub-and-board-level.md)).
420
469
  _Avoid_: preference, setting, policy
421
470
 
422
471
  **Reply**:
@@ -424,37 +473,37 @@ Claude's answer to one event, shown under it on the page.
424
473
  _Avoid_: response, comment
425
474
 
426
475
  **Pending message**:
427
- A New card's message, or the owner's message in a thread, that Claude hasn't answered yet: no reply, no later Claude line on its card other than a builder status line or agent line, no later reply to its card's ask, its ask not turned or folded into a card, and its card not closed since the watcher marked it. It reads "Working on it" once the watcher prints it to the session, and the owner can edit or delete it. While one goes unanswered, the watcher Stop hook keeps the owning session's turn from ending once, naming it ([0133](docs/adr/0133-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)).
476
+ A New card's message, or the owner's message in a thread, that Claude hasn't answered yet: no reply, no later Claude line on its card other than a builder status line or agent line, no later reply to its card's ask, its ask not turned or folded into a card, and its card not closed since the watcher marked it. It reads "Working on it" once the watcher prints it to the session, and the owner can edit or delete it. While one goes unanswered, the watcher Stop hook keeps the owning session's turn from ending once, naming it ([the board records what it knows, and commands make the rule calls](docs/adr/2026-11-03-0003-the-board-records-what-it-knows-and-commands-make-the-rule-calls.md)).
428
477
  _Avoid_: unread, queued
429
478
 
430
479
 
431
480
  **Prototype**:
432
- A page that shows each option of one owner question as it would ship, built from the board's real components fed fake data. An agent records it with `board.mjs prototype add <topic>` in the site's `data/prototypes.json`, with its title, card and takes, and writes only the take files; the board serves `prototype-<topic>.html` from its one template, `board/public/prototype.html`. `question add` accepts a prototype url only for a recorded topic, with option ids a non-empty subset of its take keys in order, without repeats, and every take file written ([0089](docs/adr/0089-the-board-serves-every-prototype-from-one-template.md)).
481
+ A page that shows each option of one owner question as it would ship, built from the board's real components fed fake data. An agent records it with `board.mjs prototype add <topic>` in the site's `data/prototypes.json`, with its title, card and takes, and writes only the take files; the board serves `prototype-<topic>.html` from its one template, `board/public/prototype.html`. `question add` accepts a prototype url only for a recorded topic, with option ids a non-empty subset of its take keys in order, without repeats, and every take file written ([the board serves every prototype from one template](docs/adr/2026-11-01-1448-the-board-serves-every-prototype-from-one-template.md)).
433
482
  _Avoid_: mockup, demo page
434
483
 
435
484
  **Prototype round**:
436
- One set of takes for an owner question, numbered per topic: the question the session posts with `round_of` naming the question it answers. A topic's head shows its latest round, orange while being made, blue while back and grey "Round N closed · take X" once a pick settles it, with a note or none, the note being the build's guidance. An answer with a note and no take leaves the card unready to build until a take is picked; the eye on a round question, or such a note asking for another prototype, starts the next round ([0111](docs/adr/0111-a-prototype-round-ends-with-a-one-take-confirm.md), [0114](docs/adr/0114-a-pick-with-no-note-settles-a-prototype-round.md), [0150](docs/adr/0150-a-prototype-pick-is-the-builds-go.md)).
485
+ One set of takes for an owner question, numbered per topic: the question the session posts with `round_of` naming the question it answers. A topic's head shows its latest round, orange while being made, blue while back and grey "Round N closed · take X" once a pick settles it, with a note or none, the note being the build's guidance. An answer with a note and no take leaves the card unready to build until a take is picked; the eye on a round question, or such a note asking for another prototype, starts the next round ([a prototype round ends with a one-take confirm](docs/adr/2026-11-02-1332-a-prototype-round-ends-with-a-one-take-confirm.md), [a pick with no note settles a prototype round](docs/adr/2026-11-02-1607-a-pick-with-no-note-settles-a-prototype-round.md), [a prototype pick is the build's go, and more of the skill moves into code](docs/adr/2026-11-03-0504-a-prototype-pick-is-the-builds-go.md)).
437
486
  _Avoid_: iteration, pass
438
487
 
439
488
  **Confirm**:
440
- The one-option "Is this it?" question on a take the owner picked with a note, which sessions opened with `question confirm` before a pick became the build's go. Confirms already on a board still render, and an answer to one settles its round; nothing opens new ones ([0116](docs/adr/0116-a-confirm-waits-for-claudes-update.md), [0150](docs/adr/0150-a-prototype-pick-is-the-builds-go.md)).
489
+ The one-option "Is this it?" question on a take the owner picked with a note, which sessions opened with `question confirm` before a pick became the build's go. Confirms already on a board still render, and an answer to one settles its round; nothing opens new ones ([a confirm waits for Claude's update](docs/adr/2026-11-02-1700-a-confirm-waits-for-claudes-update.md), [a prototype pick is the build's go, and more of the skill moves into code](docs/adr/2026-11-03-0504-a-prototype-pick-is-the-builds-go.md)).
441
490
  _Avoid_: confirm round, re-grill, final check
442
491
 
443
492
  **Prototype request**:
444
- The owner asking, from a card's thread or with a question's eye on Waiting on you, for throwaway prototype pages to compare options. One from Waiting on you names its question, which reads Prototype requested, with answering off, until its round arrives ([0111](docs/adr/0111-a-prototype-round-ends-with-a-one-take-confirm.md), [0126](docs/adr/0126-each-question-has-its-own-prototype-eye.md)). Each prototype comes with an open question on its card, and the page's switcher can send the pick; until the owner picks, the card carries Action needed and keeps its lane, Todo while it hasn't started ([0015](docs/adr/0015-prototypes-come-on-request.md), [0059](docs/adr/0059-an-unstarted-card-waits-on-its-questions-in-todo.md)).
493
+ The owner asking, from a card's thread or with a question's eye on Waiting on you, for throwaway prototype pages to compare options. One from Waiting on you names its question, which reads Prototype requested, with answering off, until its round arrives ([a prototype round ends with a one-take confirm](docs/adr/2026-11-02-1332-a-prototype-round-ends-with-a-one-take-confirm.md), [each question has its own prototype eye](docs/adr/2026-11-02-1822-each-question-has-its-own-prototype-eye.md)). Each prototype comes with an open question on its card, and the page's switcher can send the pick; until the owner picks, the card carries Action needed and keeps its lane, Todo while it hasn't started ([prototypes come only when obviously helpful or on request](docs/adr/2026-10-29-1639-prototypes-come-on-request.md), [an unstarted card waits on its questions in Todo, and its one action button follows what it waits on](docs/adr/2026-10-30-1309-an-unstarted-card-waits-on-its-questions-in-todo.md)).
445
494
  _Avoid_: mockup request, preview
446
495
 
447
496
  **Take**:
448
- One option of an owner question shown as what it would be: a framed prototype, or a diagram of boxes and arrows with what it means in practice. A prototype's take is a key (one capital letter), a label and a file, `public/prototypes/<topic>/<KEY>.js`, whose `render(stage, kit)` draws it into the page's stage. Waiting on you keeps takes in option order with the recommended one tagged: small takes share a grid, while a question with a single take, or with any scrolling or full-screen prototype, shows a choice row above one full-width take, which a choice switches in place, followed by the note and Send ([0048](docs/adr/0048-a-questions-takes-show-inline.md), [0089](docs/adr/0089-the-board-serves-every-prototype-from-one-template.md)).
497
+ One option of an owner question shown as what it would be: a framed prototype, or a diagram of boxes and arrows with what it means in practice. A prototype's take is a key (one capital letter), a label and a file, `public/prototypes/<topic>/<KEY>.js`, whose `render(stage, kit)` draws it into the page's stage. Waiting on you keeps takes in option order with the recommended one tagged: small takes share a grid, while a question with a single take, or with any scrolling or full-screen prototype, shows a choice row above one full-width take, which a choice switches in place, followed by the note and Send ([a question's takes show inline, and back goes one step](docs/adr/2026-10-29-1639-a-questions-takes-show-inline.md), [the board serves every prototype from one template](docs/adr/2026-11-01-1448-the-board-serves-every-prototype-from-one-template.md)).
449
498
  _Avoid_: variant (the switcher's URL parameter, not the word), mockup
450
499
 
451
500
  **Kit**:
452
- What a prototype's take gets as `render`'s second argument, from `board/public/prototype-kit.js`: the real sidebar, Hub page, cards and a sheet drawn in the stage's flow, fake data, a toast and `kit.on`. Inside the stage a link or form only toasts, and the listeners and timers a take adds end when another take shows ([0089](docs/adr/0089-the-board-serves-every-prototype-from-one-template.md)).
501
+ What a prototype's take gets as `render`'s second argument, from `board/public/prototype-kit.js`: the real sidebar, Hub page, cards and a sheet drawn in the stage's flow, fake data, a toast and `kit.on`. Inside the stage a link or form only toasts, and the listeners and timers a take adds end when another take shows ([the board serves every prototype from one template](docs/adr/2026-11-01-1448-the-board-serves-every-prototype-from-one-template.md)).
453
502
  _Avoid_: harness, helpers
454
503
 
455
504
  ## Board page files
456
505
 
457
- The board page's scripts in `board/public/` are plain scripts with no bundler, loaded in the order `app.html`, the app shell, lists them, from `/_hub/app/`. The `ui*.js` files hold pure renderers on the `BoardUI` global, which `ui.test.mjs` tests. `app.js` defines `BoardView`, and each `app-*.js` file after it registers one part of the board view with `BoardView.part((B) => …)`. `BoardView.create(root, site, opts)` gives each board its own `B` (state, `ClaudeSite.site`, store, and a `$` scoped to the view's root), and a part adds listeners, intervals, timers, watches and unmount steps only through `B.on`, `B.every`, `B.later`, `B.watch` and `B.atUnmount`, so `unmount()` leaves none behind; `view.test.mjs` checks that. Nothing waits while the owner types: a repaint patches the lanes and each thread in place, and a box being typed in keeps its text, cursor and focus ([0057](docs/adr/0057-a-repaint-patches-in-place-so-nothing-waits-while-you-type.md)). An open card moves to its new place at once and the page follows it: the box being typed in, else the open card's title row, stays where it was on screen ([0063](docs/adr/0063-an-open-card-moves-at-once-and-the-page-follows-it.md)); `view.test.mjs` checks both on a board mounted on `board/mini-dom.mjs`, a small DOM. The board's other views (`view-*.js`) get the same site, `$` and recorders from `BoardView.page(root, site, run)`. The view's state, such as `offline` and `data-board`, sits on its root (`.view-board`), not on `<body>`. A site card names the files it expects to touch from this table ([0022](docs/adr/0022-site-cards-build-in-parallel-when-their-files-dont-overlap.md)).
506
+ The board page's scripts in `board/public/` are plain scripts with no bundler, loaded in the order `app.html`, the app shell, lists them, from `/_hub/app/`. The `ui*.js` files hold pure renderers on the `BoardUI` global, which `ui.test.mjs` tests. `app.js` defines `BoardView`, and each `app-*.js` file after it registers one part of the board view with `BoardView.part((B) => …)`. `BoardView.create(root, site, opts)` gives each board its own `B` (state, `ClaudeSite.site`, store, and a `$` scoped to the view's root), and a part adds listeners, intervals, timers, watches and unmount steps only through `B.on`, `B.every`, `B.later`, `B.watch` and `B.atUnmount`, so `unmount()` leaves none behind; `view.test.mjs` checks that. Nothing waits while the owner types: a repaint patches the lanes and each thread in place, and a box being typed in keeps its text, cursor and focus ([a repaint patches in place, so nothing waits while you type](docs/adr/2026-10-30-1122-a-repaint-patches-in-place-so-nothing-waits-while-you-type.md)). An open card moves to its new place at once and the page follows it: the box being typed in, else the open card's title row, stays where it was on screen ([an open card moves at once and the page follows it](docs/adr/2026-10-30-1637-an-open-card-moves-at-once-and-the-page-follows-it.md)); `view.test.mjs` checks both on a board mounted on `board/mini-dom.mjs`, a small DOM. The board's other views (`view-*.js`) get the same site, `$` and recorders from `BoardView.page(root, site, run)`. The view's state, such as `offline` and `data-board`, sits on its root (`.view-board`), not on `<body>`. A site card names the files it expects to touch from this table ([site cards build in parallel when their files don't overlap](docs/adr/2026-10-29-1639-site-cards-build-in-parallel-when-their-files-dont-overlap.md)).
458
507
 
459
508
  Refs in text that Claude or the owner wrote are linked by the renderer, never by hand: pass the text through `ui-links.js` (`linkText`, or `linkHtml` for an HTML reply or line) with the item's `linkContext`. A card's ref (`INT-<n>`, `#n` for a GitHub ticket, or any `ref` on the board) or its id opens its card, a Linear id or PR opens its page, and a bare URL becomes a link. Write refs as plain text in thread lines, replies, questions and plans.
460
509
 
@@ -467,29 +516,30 @@ Refs in text that Claude or the owner wrote are linked by the renderer, never by
467
516
  | `ui.js` | Shared helpers: escaping, times, reply bodies, attachments, icons and message buttons, badges by tone, `setHTML`, which patches a region in place and keeps the focused field's focus when it moves, and `fetchJSON`, through which the side pages read the API and wait out a board restart |
468
517
  | `ui-links.js` | Linking refs, Linear ids, PRs and URLs in written text; load it right after `ui.js` |
469
518
  | `ui-enums.js` | `BoardUI.BUTTON` and `BoardUI.ACTION_KIND`, the **action button**'s enums, shared with `board/domain.mjs`, which runs it in a vm context; load it before `ui-threads.js` and `ui-cards.js`. `view.test.mjs` checks that every action kind makes one button orange and every action button draws |
470
- | `ui-order.js` | `BoardUI.laneOrder`, the board's order of its items ([0140](docs/adr/0140-each-lane-has-one-fixed-order.md)), shared with `board/domain.mjs`, which runs it in a vm context, so a tap the page draws at once lands where the server puts it |
471
- | `ui-cards.js` | A card's lines, in order: title with its ticket badge, or New chip on an unsorted ask (none once sorted); status with its ETA; Stalled when the builder is silent, then PR, review and other chips, then the try badge (Visit or Install, with running, failed and stale states); its lineup's grey wave chip; last the time its lane sorts by, its hold, blocked by, Action needed and its unread count; the Hold sheet's picker; and at its top right a New card's bump, edit and delete icons, or another bumpable card's bump icon, filled orange once bumped; and the action row's Merge and Serve/Build buttons, main's bar and build wording |
472
- | `ui-sidebar.js` | `BoardUI.sidebar`, the sidebar's markup from `/_hub/sidebar.json`, with the New version row from `updateRow`, Reload or the npm update's Upgrade, headed by `BoardUI.header` itself, with each row's key in **switch mode**; `switchKeys`, which row each key opens; `othersWaiting`, for the logo's label; and `shortcuts`, the **shortcuts sheet**'s content from the one list of shortcuts. Needs `ui-page-header.js` loaded before it: `hub/hub.mjs` renders the app shell's first sidebar with both in a vm context |
519
+ | `ui-patch.js` | `BoardUI.boardPatch` and `applyPatch`, the board's per-card patches: cards by key, questions and topics by id, every other part whole when it changed ([the board sends per-card patches](docs/adr/2026-11-04-0332-the-board-sends-per-card-patches.md)), shared with `board/server.mjs`, which runs it in a vm context |
520
+ | `ui-order.js` | `BoardUI.laneOrder`, the board's order of its items ([each lane has one fixed order](docs/adr/2026-11-03-0223-each-lane-has-one-fixed-order.md)), shared with `board/domain.mjs`, which runs it in a vm context, so a tap the page draws at once lands where the server puts it |
521
+ | `ui-cards.js` | A card's lines, in order: title with its ticket badge, or New chip on an unsorted ask (none once sorted); status with its ETA, red and a nudge when the builder is silent; then PR, review and other chips, then the try badge (Visit or Install, with running, failed and stale states); its lineup's grey wave chip; last the time its lane sorts by, its hold, blocked by, Action needed, an In Progress card's phase bars and its unread count; the Hold sheet's picker; and at its top right a New card's bump, edit and delete icons, or another bumpable card's bump icon, filled orange once bumped; and the action row's Merge and Serve/Build buttons, main's bar and build wording |
522
+ | `ui-phase-bars.js` | `BoardUI.phaseBars(strip, phases)`, the phase bars for any list of phases: an In Progress card's five build phases (`ui-cards.js`) and a starting board's three start steps (`ui-sidebar.js`), a running one pulsing and a `fill` percent filling the next. Needs nothing else: `hub/hub.mjs` renders the app shell's first sidebar with it in a vm context; load it before `ui-cards.js` and `ui-sidebar.js` |
523
+ | `ui-sidebar.js` | `BoardUI.sidebar`, the sidebar's markup from `/_hub/sidebar.json`, with the New version row from `updateRow`, Reload or the npm update's Upgrade, headed by `BoardUI.header` itself, with each row's key in **switch mode**; `switchKeys`, which row each key opens; `othersWaiting`, for the logo's label; `shortcuts`, the **shortcuts sheet**'s content from the one list of shortcuts; and `startCaption`, a starting board's step and seconds. Needs `ui-phase-bars.js` and `ui-page-header.js` loaded before it: `hub/hub.mjs` renders the app shell's first sidebar with all three in a vm context |
473
524
  | `sidebar.js` | Painting the sidebar from the copy written into the shell, else this device's last copy, then from each copy the hub's stream sends; this device's push subscription for its Turn on row; the logo's toggle, the drawer and its swipes, the rail's collapse, which this device keeps, and the logo's label; **switch mode**'s keys, from the document and a framed page, each row opened through the shell; the **shortcuts sheet**'s h h and Escape |
474
525
  | `app.html` | The app shell: the sidebar, the view's slot, and its scripts and CSS from `/_hub/app/`, with a board's loads started in its `<head>`; the hub serves it for a browser's load of `/` or a site's page outside try URLs, and every load of a hub page, with the sidebar and its data written in (`hub/shell.mjs` `pageOf`), and the board server for a board's four view paths without them (`shellHtml`) |
475
526
  | `router.js` | `AppRouter`: every hub URL as a view and each view as its URL (`ui.test.mjs` tests both), the views the shell mounts in place, framed pages included, and catching taps on links to them and back and forward, with `{idx}` in each history entry and `pushed` on one a push opened; a back arrow goes one step back by them. On the **page tree** each entry also carries `up`, how many of its parents sit under it, which the router writes on every way in, and the arrow goes up a level. It frames the paths `hub/shell.mjs` `pageOf` answers with the shell, which `hub/shell.test.mjs` checks |
476
527
  | `shell.js` | `AppShell`: the hub code check that shows New version with an owner-tapped Reload, the sidebar mounted once, one view at a time, asking before leaving an unsaved edit, `/`'s pick of a board, the hub's one stream and which left boards are unchanged, a framed page's URL and title copied to the top, a push tap from `hub/sw.js` or a framed page's view URL (`AppShell.open`) routed in place, and registering `hub/sw.js`, which opens the shell while the host is asleep |
477
- | `view-settings.js` | Board Settings as a modal over its board, which shell.js mounts: repo and branch (Change uses the same list and GitHub link search as New board), | `view-settings.js` | Board Settings as a modal over its board, which shell.js mounts: repo and branch (Change uses the same list and GitHub link search as New board), ticket source, auto-merge, auto-build, auto-pull, auto-triage, reviewers, rules and Close board with its typed-name sheet |
528
+ | `view-settings.js` | Board Settings as a modal over its board, which shell.js mounts: repo and branch (Change uses the same list and GitHub link search as New board), | `view-settings.js` | Board Settings as a modal over its board, which shell.js mounts: repo and branch (Change uses the same list and GitHub link search as New board), ticket source, auto-merge, auto-build, auto-pull (Auto implement Todo cards) with Maximum parallel implementers, auto-triage, reviewers, rules and Close board with its typed-name sheet |
478
529
  | `view-questions.js` | Waiting on you as a view: a topic's questions, their takes framed with `?take=` in a fitting grid or a chooser above one full-width frame, which a choice switches in place through the frame's `PrototypeSwitcher.current`, each question's eye, which asks for a prototype of that question, and one Send, which stays while the topic has a question open and otherwise opens the next topic with one, or goes back to the board |
479
530
  | `view-notes.js` | One item's notes, or with `?wave=` a lineup's goal, order and note, as a view, from `GET /api/notes`; the server redirects `plan.html` to `notes.html` |
480
531
  | `view-hub.js` | The **hub page** as a view, from `/_hub/api/hub`, refreshed every 30 seconds while it shows; the Usage card, whose Claude model posts `/_hub/settings/claude-model`, Codex share posts `/_hub/settings/codex` and pause line posts `/_hub/settings/pause-at`, with Keep going and Stop banners posting `/_hub/settings/keep-going`, pending prompts of sessions with no board, Send now, then `view-hub-settings.js` below its status |
481
- | `view-hub-settings.js` | Summary rows opening **hub settings** modals over the hub page, from `/_hub/api/settings`: Notifications with Snooze and Keep awake with their one duration picker (`durationPicker`: chips and a native Custom picker), Polling, Linear (`linear-key.js`’s slot), Rules for every board and Closed boards with Reopen |
532
+ | `view-hub-settings.js` | Summary rows opening **hub settings** modals over the hub page, from `/_hub/api/settings`: Notifications with Snooze and Keep awake with their one duration picker (`durationPicker`: chips and a native Custom picker), Quiet hours, Linear (`linear-key.js`’s slot), Rules for every board and Closed boards with Reopen |
482
533
  | `linear-key.js` | `LinearKey`, Hub’s Linear key slot: the masked key or why it doesn’t work, the link to where keys are made, saving on paste, change or Enter with Remove, and the same slot as a modal over Board Settings or New board, which the Tickets control opens when Linear is tapped without a working key |
483
- | `view-polling.js` | The editor in Hub’s Polling modal, from `/_hub/api/polling`: the day bar, whose taps pick a window without asking the hub, each window's edits, the overnight hold, the daily wakes and Send now |
484
534
  | `ui-hub.js` | `HubUI`, the hub views' pure renderers: rows, tiles, the flash, the Now row, this device's row, pause banners and the Usage card with the pause line stepper and ticks |
485
535
  | `hub-kit.js` | `HubKit`, what the hub views share: `live` (load, the header's time and ↻, the 30-second refresh), `forms` (posting a hub form for JSON, and saving a toggle or time on change) and `device` (this device's push subscription) |
486
536
  | `view-frame.js` | Any other page as a frame view: the frame beside the board header with Open alone ↗, hiding that header for a page that draws its own, whose logo then toggles the sidebar; each load's URL and title to the shell, and taps on links to other views sent to it, a prototype's back arrow included, which the shell takes up the **page tree** before the page's own script can |
487
537
  | `sidebar.css` | The sidebar's rail, its collapse, the drawer and switch mode, plus the shared New board dialog and the shortcuts sheet; linked after `colors.css` |
488
538
  | `hub.css` | The hub views' CSS and the hub's down page's, every rule under `.hub-view`, the class on a hub view's root, on the down page's `<html>` and on the board's Hold sheet picker, which shares the duration picker's rules; the shell links it after `style.css`, whose header the hub views share, and the down page as `/_hub/hub.css` |
489
539
  | `ui-page-header.js` | `BoardUI.header`, every page's header: the logo (which toggles the sidebar), a back arrow where needed (beside a phone-only logo), the title, then the time and ↻, a board's bulb, and the gear, or a page's own trail. On a page of its own, the back arrow's own script goes one step back, or to its href after a push; in the app shell `router.js` does that. Needs nothing else: `server.mjs` renders each page's `<!--header {…}-->` with it, such as a prototype's, and `hub/hub.mjs` the shell's first sidebar, whose head is one too (`ui-sidebar.js`), each in a vm context |
490
- | `ui-header.js` | The header's time, or Paused until from the shell's pause state, and when it moves, the GitHub status line and its Hub links mark, the Hub links list, the setup checklist, when a refresh asks for a GitHub check, and which board header controls take taps |
540
+ | `ui-header.js` | The header's time, or paused until from the shell's pause state, and when it moves, the GitHub status line and its Hub links mark, the Hub links list, the setup checklist, when a refresh asks for a GitHub check, and which board header controls take taps |
491
541
  | `ui-threads.js` | Thread messages, with link, status and agent lines, the open card's window over them with its Show more, and the reply form's Done |
492
- | `ui-questions.js` | Owner question cards with their takes inline and diagrams, answer history, prototype status, a confirm's take link, the topic head's round chip and the Waiting on you topic row; `BoardUI.nextQuestion`, the pure move-on rule shared by Send and a prototype pick, and `sentNotice`, the Sent line the board reads on return |
542
+ | `ui-questions.js` | Owner question cards with their takes inline and diagrams, answer history, prototype status, a confirm's take link, the topic head's round chip and the Waiting on you topic row; `cardTopics`, which names a card's question topic from its card; `BoardUI.nextQuestion`, the pure move-on rule shared by Send and a prototype pick, and `sentNotice`, the Sent line the board reads on return |
493
543
  | `ui-markdown.js` | The Markdown subset `view-notes.js` renders a card's notes with |
494
544
  | `ui-snapshot.js` | The last visit's stored shape and size cap, which threads preload, which controls wait for the fresh board, which lines flash, and what counts as a card's update |
495
545
  | `attach.js` | Picking and uploading attachments, each to the site of the board view around its composer |
@@ -501,12 +551,14 @@ Refs in text that Claude or the owner wrote are linked by the renderer, never by
501
551
  | `rules-editor.js` | `RulesEditor`, the rules list on Board Settings and the Hub page, with its own CSS; `ui.test.mjs` tests its pure parts |
502
552
  | `app-threads.js` | Loading a thread, once at a time per card; an open card's thread, its reply box, quick replies and Done |
503
553
  | `app-cards.js` | Cards, their open detail with the details list ending in Notes ↗ · Visit/Install ↗ · Review on GitHub ↗ when present, and the workflow row: Merge, Hold, the **action button**, Serve/Build and rightmost **Implement**, each confirming but Hold, which opens its sheet with the duration picker; try requests, failure-thread links and main’s failed-build log and Retry sheet; the bump icon's bump and unbump, with no confirmation; an ask's detail shows only its action button; the thread's Done confirmation and send |
504
- | `app-lanes.js` | Lanes, Done's and Asks' Show more, Done's finished-wave folds, the **Waves section** with its filter and Triage, and Plan waves |
505
- | `app-asks.js` | The + sheet and its press-n-twice shortcut, and bump, edit and delete |
554
+ | `app-lanes.js` | Lanes, Done's and Asks' Show more, Done's finished-wave folds, Todo's **wave bands** with their Implement, Triage and ⋯ moves, and Plan waves |
555
+ | `new-task.js` | The + button, its new-task sheet and press-n-twice shortcut, on every page of a board |
556
+ | `app-asks.js` | Bump, edit and delete for a New card or pending message, and ⌘↵ in a thread box |
506
557
  | `app-needs.js` | The Needs you box, led by the board session's pending prompts |
507
558
  | `ui-prompts.js` | A pending prompt's Needs you line: its details, Allow once, Always allow and Deny, or a question's options, Skip and Send |
508
559
  | `prompts.js` | `PromptAnswers`, answering pending prompts from their lines on a board and the hub page: which taps send at once, Always allow's confirmation, and the picks a Send waits on |
509
560
  | `app-arch.js` | The header's bulb and its **architecture review** sheet: the last review, Run with its confirm, what a review waits on, and the bulb's glow while one runs |
561
+ | `app-reader.js` | The **reader sheet**: a builder's log (readable or raw, following it as it grows) and a card's or lineup's Notes, opened over the board from their links, closing on ✕, Escape, the dim area or Back |
510
562
  | `app-banner.js` | The answer banner, its tap and its ✕ |
511
563
  | `app-header.js` | The board's header controls and time, refresh, the offline state, the In Review header's GitHub line, the Hub links sheet and the setup checklist |
512
564
  | `app-snapshot.js` | Reading and saving the last visit, also as the view unmounts, keeping every board's within three at the cap, holding the controls that send while it shows, the flash when the fresh board lands, and each card's sign: the flash on a card that changed lanes or took a New task's place, and the tint on a card otherwise updated, unless the owner changed it from this page |