@staix/agent-hub 0.12.23 → 0.12.25

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 (161) hide show
  1. package/CHANGELOG.md +109 -1
  2. package/README.md +8 -3
  3. package/docs/addons/claude-mem.md +24 -0
  4. package/docs/addons/codex-plugin.md +8 -0
  5. package/docs/addons/dot-admit.md +8 -0
  6. package/docs/addons/open-code-review.md +8 -0
  7. package/docs/addons/ponytail.md +23 -0
  8. package/docs/addons/ripwire.md +22 -0
  9. package/docs/agent-notes/README.md +5 -0
  10. package/docs/agent-notes/adapters.md +10 -1
  11. package/docs/agent-notes/bus.md +3 -1
  12. package/docs/agent-notes/daemon.md +7 -1
  13. package/docs/agent-notes/local-worker.md +4 -2
  14. package/docs/agent-notes/tasks.md +8 -0
  15. package/docs/agent-notes/tests.md +5 -1
  16. package/docs/bench.md +28 -3
  17. package/docs/cooperbench.md +4 -0
  18. package/docs/data-policy.md +36 -0
  19. package/docs/events.md +3 -0
  20. package/docs/gsd-collaboration-analysis.md +48 -0
  21. package/docs/memory.md +231 -0
  22. package/docs/operations.md +666 -19
  23. package/docs/plans/2026-10-11-issues-109-sequential.md +81 -0
  24. package/docs/plans/2026-10-11-routing-evaluation-proposal.md +30 -0
  25. package/docs/profiles.md +57 -0
  26. package/docs/quickstart.md +2 -2
  27. package/docs/research.md +31 -1
  28. package/docs/roles.md +85 -0
  29. package/docs/sdlc.md +170 -0
  30. package/docs/security.md +111 -4
  31. package/docs/smoke.md +288 -0
  32. package/docs/specs/2026-09-19-agent-hub-design.md +633 -7
  33. package/docs/specs/2026-10-12-backlog-implementation-plan.md +186 -0
  34. package/docs/specs/2026-10-12-office-view-design.md +212 -0
  35. package/docs/text-projection.md +19 -0
  36. package/docs/verification/2026-10-11-acp-watch-t0.md +33 -0
  37. package/docs/verification/2026-10-11-agent-config-inventory.md +20 -0
  38. package/docs/verification/2026-10-11-jcode-peer-contract.md +27 -0
  39. package/docs/verification/2026-10-13-0.12.24.md +94 -0
  40. package/docs/verification/2026-10-13-board-phone.md +31 -0
  41. package/docs/verification/2026-10-13-fsmonitor-fixture-attribution.md +19 -0
  42. package/docs/verification/2026-10-14-0.12.24-audit.md +123 -0
  43. package/docs/verification/2026-10-14-0.12.25.md +27 -0
  44. package/docs/verified.json +22 -13
  45. package/package.json +2 -1
  46. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  47. package/plugins/agent-hub/ROLE-NOTICE.md +26 -0
  48. package/plugins/agent-hub/server.js +1175 -339
  49. package/scripts/check-docs.mjs +129 -0
  50. package/src/adapters/acp.ts +112 -13
  51. package/src/adapters/claude-channel.ts +48 -11
  52. package/src/adapters/codex-appserver.ts +11 -0
  53. package/src/adapters/jcode.ts +110 -0
  54. package/src/adapters/local-worker.ts +10 -7
  55. package/src/adapters/pi.ts +171 -23
  56. package/src/cli/attention.ts +60 -0
  57. package/src/cli/bench.ts +24 -5
  58. package/src/cli/board-read.ts +12 -0
  59. package/src/cli/console-state.ts +103 -17
  60. package/src/cli/console.ts +54 -8
  61. package/src/cli/facts-hook.ts +12 -4
  62. package/src/cli/help.ts +35 -9
  63. package/src/cli/identity.ts +18 -7
  64. package/src/cli/init.ts +48 -10
  65. package/src/cli/jcode-mcp.ts +58 -0
  66. package/src/cli/kimi-mcp.ts +53 -0
  67. package/src/cli/launch.ts +16 -1
  68. package/src/cli/main.ts +392 -57
  69. package/src/cli/memory.ts +193 -0
  70. package/src/cli/output.ts +45 -4
  71. package/src/cli/pet-config.ts +1 -0
  72. package/src/cli/pet.ts +83 -0
  73. package/src/cli/preview.ts +38 -5
  74. package/src/cli/status-lines.ts +1 -1
  75. package/src/cli/tail-render.ts +1 -0
  76. package/src/cli/upgrade-runtime.ts +32 -3
  77. package/src/cli/watch.ts +31 -0
  78. package/src/hub/activity.ts +53 -0
  79. package/src/hub/ask.ts +10 -5
  80. package/src/hub/bench.ts +10 -3
  81. package/src/hub/board.ts +222 -16
  82. package/src/hub/bus.ts +48 -9
  83. package/src/hub/citations.ts +7 -0
  84. package/src/hub/conductor.ts +12 -7
  85. package/src/hub/config-trust.ts +4 -2
  86. package/src/hub/crash.ts +9 -0
  87. package/src/hub/daemon.ts +914 -120
  88. package/src/hub/delivery-journal.ts +5 -0
  89. package/src/hub/envelope.ts +1 -1
  90. package/src/hub/events.ts +12 -2
  91. package/src/hub/facts.ts +26 -7
  92. package/src/hub/git.ts +8 -2
  93. package/src/hub/github-import.ts +28 -0
  94. package/src/hub/hub-tools.ts +49 -10
  95. package/src/hub/inference.ts +1 -1
  96. package/src/hub/lifecycle-schema.ts +17 -0
  97. package/src/hub/listen.ts +15 -0
  98. package/src/hub/manager.ts +12 -5
  99. package/src/hub/path-policy.ts +115 -0
  100. package/src/hub/peer-catalog.ts +28 -0
  101. package/src/hub/permission-mode.ts +19 -5
  102. package/src/hub/planning.ts +70 -0
  103. package/src/hub/profiles.ts +74 -0
  104. package/src/hub/projected-diff.ts +73 -0
  105. package/src/hub/projection-exec.ts +24 -0
  106. package/src/hub/research.ts +144 -21
  107. package/src/hub/roles.ts +123 -0
  108. package/src/hub/roster.ts +23 -0
  109. package/src/hub/routing.ts +18 -5
  110. package/src/hub/sdlc-queue.ts +112 -0
  111. package/src/hub/sdlc-release.ts +125 -0
  112. package/src/hub/sdlc.ts +250 -0
  113. package/src/hub/settings.ts +34 -15
  114. package/src/hub/shipped-roles.ts +25 -0
  115. package/src/hub/snapshots.ts +89 -15
  116. package/src/hub/start-mode.ts +7 -5
  117. package/src/hub/supervision.ts +1 -0
  118. package/src/hub/task-sweep.ts +1 -1
  119. package/src/hub/tasks.ts +905 -89
  120. package/src/hub/text-projection.ts +151 -0
  121. package/src/hub/tooling.ts +170 -0
  122. package/src/hub/ui.ts +16 -2
  123. package/src/hub/workflow.ts +71 -0
  124. package/src/local/sandbox.ts +6 -4
  125. package/src/local/tools.ts +11 -6
  126. package/src/memory/brief.ts +28 -14
  127. package/src/memory/import.ts +55 -0
  128. package/src/memory/recall.ts +84 -0
  129. package/src/memory/store.ts +757 -0
  130. package/src/memory/sync.ts +145 -0
  131. package/src/pet/NOTICE.md +10 -0
  132. package/src/pet/characters.ts +1438 -0
  133. package/src/pet/config.ts +31 -0
  134. package/src/pet/frame.ts +17 -0
  135. package/src/pet/pixels.ts +28 -0
  136. package/src/pi/extension.ts +40 -5
  137. package/src/role-text.d.ts +1 -0
  138. package/src/ui/index.html +843 -46
  139. package/src/ui/needs.ts +58 -0
  140. package/src/ui/office-model.ts +440 -0
  141. package/src/ui/peer-palette.ts +16 -0
  142. package/src/ui/task-board.ts +49 -0
  143. package/src/ui/task-progress.ts +5 -1
  144. package/templates/AGENTS.block.md +3 -2
  145. package/templates/config.json +5 -1
  146. package/templates/profiles/dev.json +22 -0
  147. package/templates/profiles/general.json +26 -0
  148. package/templates/profiles/research.json +57 -0
  149. package/templates/profiles/writing.json +28 -0
  150. package/templates/roles/NOTICE.md +26 -0
  151. package/templates/roles/dev/backend-engineer.md +26 -0
  152. package/templates/roles/dev/code-reviewer.md +26 -0
  153. package/templates/roles/dev/frontend-engineer.md +26 -0
  154. package/templates/roles/dev/security-reviewer.md +26 -0
  155. package/templates/roles/dev/software-architect.md +26 -0
  156. package/templates/roles/dev/test-engineer.md +26 -0
  157. package/templates/roles/research/analyst.md +26 -0
  158. package/templates/roles/research/fact-checker.md +26 -0
  159. package/templates/roles/research/research-lead.md +26 -0
  160. package/templates/roles/research/researcher.md +26 -0
  161. package/templates/roles/research/statistician.md +26 -0
@@ -1,6 +1,6 @@
1
1
  # Operations guide
2
2
 
3
- This guide describes ahub 0.12.23 and control protocol 16. Live verification
3
+ This guide describes ahub 0.12.25 and control protocol 16. Live verification
4
4
  results and remaining prerequisites are recorded separately in [the smoke ledger](smoke.md).
5
5
 
6
6
  ## Command output
@@ -63,6 +63,25 @@ a three-line footer, separated by ASCII `-` rules; the stream has one rule above
63
63
  its footer. The active tab is bracketed, as in `[2 Approvals]`, so it reads
64
64
  without color. The Approvals tab counts pending requests and the Queue tab
65
65
  counts `needs_review` deliveries, in the attention and failure tones.
66
+
67
+ The console attention companion (#280) shows waiting, blocked, review, working,
68
+ idle or asleep with separate action/watch counts. `n` selects the exact approval,
69
+ held queue or review row, or prints applicable guidance; it never answers a
70
+ request or runs a command. Editing, choices and confirmation retain their controls.
71
+ `P` cycles the five built-in characters and off for the current console.
72
+
73
+ Configure `pet` in `.agenthub/config.json` or `config.local.json`; local options
74
+ override shared ones. Defaults are `character: "stai"`, `size: "line"`,
75
+ `glyphs: "auto"`, `blink: true`, `bell: false`. Line preserves the three footer
76
+ rows and prompt position. Mini/full reserve a bounded character rectangle and
77
+ fall back when the terminal is too small. Supported glyphs and character choices
78
+ are described below. `pet: false` or `ahub console --no-pet` disables presentation.
79
+ Unknown options produce one bounded notice and fall back. Only an open approval
80
+ blinks through the existing redraw; `blink: false` disables it. The optional bell
81
+ sounds on an action-count transition from zero, at most once per minute, never
82
+ for a message alone. Plain mode prints the line only when the action count changes.
83
+ Messages addressed to `user` remain attention items until the next key. Drawing
84
+ adds no timer, network request or writable settings path.
66
85
  Tabs change with the digits 1 to 5 or with Left and Right (wrapping at both
67
86
  ends), never while a command is being edited or a choice is open; under a
68
87
  confirmation an arrow dismisses it like any key but y, without moving a tab. A pasted
@@ -148,6 +167,60 @@ OS color preference through CSS. Both inline scripts and the style retain CSP
148
167
  hashes; there are no external chart/theme assets. Live theme/readability inspection
149
168
  is tracked in `docs/smoke.md` and remains unverified until performed.
150
169
 
170
+ The dashboard Office section (#264, phase 1 of 4) draws the same snapshot as a
171
+ static flat office: one desk per peer in a stable slot (claude, codex, kimi, pi,
172
+ local, then others by id; a peer going offline dims its desk and never moves
173
+ another), rooms for the board columns in a fixed order (To Do, Work floor,
174
+ Review, Done shelf as a count only), at most 8 cards per room with "+N more"
175
+ filtering the task list to that state, and at most 12 desks with "+N peers".
176
+ Work-floor cards sit at the owner's desk, marked for rework; a busy peer's task
177
+ bubble names its task only when it has exactly one in progress. Every peer
178
+ condition (idle, busy, offline, paused, waiting on approval) has a glyph and a
179
+ text label, and the scene carries ids, classes, states, kinds, counts and public
180
+ titles only: message bodies, task details and approval titles never enter it.
181
+ The scene adds no timer, frame loop or request and re-renders only when its
182
+ signature changes. A View control offers Off (the default), Flat and
183
+ Isometric; the choice is stored in a second host-scoped loopback cookie `agent-hub-office` with the
184
+ same attributes as the theme cookie, and blocked cookie access defaults to Off
185
+ without preventing operation. Desks and cards are focusable buttons; activating
186
+ one scrolls to and highlights the matching list row, and a list row highlights
187
+ its desk or card on focus and hover. The scene performs no action: every control
188
+ stays in the lists. The View control's third option, Isometric (phase 4),
189
+ renders the same model through the same code path with the grid coordinates
190
+ projected (x' = (x - y) cos 30, y' = (x + y) sin 30): tiles become
191
+ parallelograms, cards and labels stay upright, and the DOM order and
192
+ accessible names are identical to Flat. Switching the view jumps to the new
193
+ projection without animating; the settle rule and reduced motion apply
194
+ unchanged. The live browser look is tracked in `docs/smoke.md` and
195
+ remains unverified until performed.
196
+
197
+ Motion (phase 2): card moves between rooms and desks, message arcs between
198
+ desks (from the hub or the console they start at an anchor point), delivery
199
+ warning marks and the busy latch all follow the snapshot. Motion is CSS only:
200
+ transitions on transform and opacity (at most one second), keyframe fades for
201
+ the transient marks. Arcs and marks hold, then fade out ten seconds after the
202
+ event, timed at render from the model's timestamps; expired nodes purge on the
203
+ next changed render or their own animationend, never on a timer. Arcs expire on
204
+ the snapshot's own envelope clock, so an unchanged snapshot re-renders
205
+ identically and writes nothing to the DOM. The scene goes straight to final
206
+ positions on the first snapshot, after a project switch, after a snapshot gap
207
+ over three seconds, or when one snapshot brings more than six transitions.
208
+ `prefers-reduced-motion: reduce` removes all scene transitions and animations.
209
+ Event reasons and bodies never enter the scene; arcs carry from, to, kind,
210
+ priority, the task ref and the dropped flag only.
211
+
212
+ Snapshot fields (phase 3): three additive optional fields, so older pages and
213
+ older daemons mix freely and `PROTOCOL`/`EVENTS_SCHEMA` stay unchanged. A peer's
214
+ open turn (`since`, `task`, `attribution`) names the busy bubble's task exactly
215
+ instead of the single-in-progress-task heuristic, and a turn still open while
216
+ the peer is paused adds a "finishing a turn" line under the Break sign. A task's
217
+ `checking` flag draws a check-running mark on its card, which stays at its
218
+ owner's desk (rooms follow states only). Warning `links` (overlap from the
219
+ board's overlap test, cohorts, and recent turn-end conflicts the daemon keeps in
220
+ a bounded in-memory list) draw dashed lines between the desks they name, labeled
221
+ with kind and task ids; all three carry task and peer ids only, and a PII task
222
+ never joins a link.
223
+
151
224
  Console color policy is `--color=auto|always|never`, with `auto` as the default.
152
225
  Auto enables color only when both input and output are TTYs, `TERM` is not
153
226
  `dumb`, and `NO_COLOR` is empty or absent. Explicit `always` overrides these
@@ -226,7 +299,7 @@ Launch that peer with `ahub claude` for channel pushes, or select `codex` in
226
299
  observes `hub_status`, moves stalled work and obtains review before reporting
227
300
  results and open decisions. It does not implement the tasks it handed out.
228
301
  `hub_peer_start` starts a peer in the start mode a person set for it (see
229
- "Start modes"): local, Kimi and a headless Pi or Codex start at once; for a
302
+ "Start modes"): local and headless Kimi, Pi or Codex start at once; for a
230
303
  TUI peer the hub opens a terminal running the fixed `ahub <peer>` command,
231
304
  after validating it through the shared launcher planner, and when it cannot
232
305
  open one the call fails with that command for the person to run. The
@@ -622,6 +695,30 @@ ahub research backfill # build this project's records once from even
622
695
  ahub task label 12 reverted # a later verdict (ok, regressed, reverted, incomplete, wrong, abandoned)
623
696
  ```
624
697
 
698
+ ## Hub memory
699
+
700
+ The hub keeps its own memory in `~/.agenthub/memory/` beside claude-mem ([how it works](memory.md)): notes saved
701
+ against an open task are short-term; when the task is approved its decisions, contracts and fails become long-term.
702
+ Task briefs, session-start recall and `ahub ask` read it first, and the dashboard has a Memory section.
703
+
704
+ ```bash
705
+ ahub memory # this project's entries, newest first
706
+ ahub memory search parser # every word must match
707
+ ahub memory show 1a2b3c4d # one entry, its provenance and edges
708
+ ahub memory forget 1a2b3c4d # a person's; also promote, demote, supersede, rebuild
709
+ ```
710
+
711
+ `"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
712
+
713
+ Between your machines, through a private git remote, with long-term tasks that span them:
714
+
715
+ ```bash
716
+ ahub memory sync --remote git@github.com:you/agent-hub-memory.git # once per machine; then every 10 minutes
717
+ ahub goal new "native memory" # a long-term task
718
+ ahub goal # open ones, who holds each and until when
719
+ ahub goal take 1a2b3c4d --force # take one over from another machine
720
+ ```
721
+
625
722
  ## Benchmarks
626
723
 
627
724
  In a git repository kept for benchmarks (`"bench": { "enabled": true }` in its `.agenthub/config.json`, a clean tree),
@@ -915,7 +1012,7 @@ denylist (Pi and local), or native vendor boundaries (Claude and Codex).
915
1012
  | --- | --- | --- | --- |
916
1013
  | Kimi Code CLI | ACP yolo | ACP auto | ACP default |
917
1014
  | Codex | on-request for every outgoing turn/start | never for every outgoing turn/start | Restore the known native policy once, then stop overriding |
918
- | Claude | Allow resolving project file tools outside .agenthub/.git/.claude/.codex/.qwen/.kimi/.pi/.mcp.json | Hook allow for every tool | No hook decision |
1015
+ | Claude | Allow resolving project file tools outside .agenthub/.git/.claude/.codex/.qwen/.kimi/.kimi-code/.pi/.mcp.json | Hook allow for every tool | No hook decision |
919
1016
  | Pi and local | Grant write/edit outside native agent configuration paths; read never asks; shell/git writes ask | Grant each tool once within the existing sandbox/guard | Normal approval handling |
920
1017
 
921
1018
  Kimi's map applies only to the actual Kimi Code CLI identity, not another ACP
@@ -996,6 +1093,80 @@ permission_mode (peer/from/to) with no tool arguments under events schema 1.
996
1093
  The optional control requests preserve PROTOCOL; an older hub answers unknown
997
1094
  and the CLI advises upgrading.
998
1095
 
1096
+ ## Change the participating peers while the hub runs
1097
+
1098
+ `ahub roster` lists every known peer, whether it participates, its start mode,
1099
+ current state, queued messages and open tasks. `ahub roster --json` is the same
1100
+ ordered catalog view for scripts. Status and the console keep their existing lazy
1101
+ rows; an off-roster peer is shown only while it has retained messages, an uncertain
1102
+ delivery or open work, with the words `off roster`.
1103
+
1104
+ ```bash
1105
+ ahub roster
1106
+ ahub roster remove kimi --yes # print the preview, confirm and remove
1107
+ ahub roster remove kimi --yes --now # stop a busy owned runtime before handing work over
1108
+ ahub roster add kimi
1109
+ ahub settings set roster.kimi false --preview
1110
+ ahub settings set roster.kimi false --yes
1111
+ ```
1112
+
1113
+ These are person's commands and use the same settings preview, write and undo as
1114
+ the dashboard's Roster settings. An ordinary dashboard session may remove a peer;
1115
+ adding requires `ahub ui --settings` or a person's terminal. Removal requires the
1116
+ peer id as confirmation. Without `--now`, a busy peer is refused. A conductor
1117
+ holder cannot be removed until its role is moved.
1118
+
1119
+ Removal fences membership, stops hub-owned runtimes or detaches sessions in a
1120
+ person's terminal, and then hands work over. The removal preview and result name
1121
+ the peer whose existing work the person must stop in that retained terminal;
1122
+ the preview names the roles offered and those with no eligible replacement; the
1123
+ result lists the saved owner/reviewer moves and every assignment that stays. No stop notice is forced into
1124
+ a detached session and nothing bypasses the journal. Codex 0.146.0
1125
+ exits its TUI on the close-4000 disconnect and does not reconnect automatically.
1126
+ Its app-server and proxy remain available; after `ahub roster add codex`, run
1127
+ `ahub codex resume <thread-id>` (the full id is printed in the preview, removal
1128
+ result and return) or `ahub codex resume` to select its previous native session. Removal never closes
1129
+ the terminal window itself. The Claude channel retries and reconnects on return.
1130
+ Pi return retains the verified owner's monotonic generation even after refused
1131
+ native activity while detached; it shares no personal output and invalidates any
1132
+ cached empty-session resume proof after that activity. Return also needs the
1133
+ current hub extension, which fences prompt admission: a TUI still running an
1134
+ older extension is refused (restart its retained terminal), and a return whose
1135
+ snapshot raced native activity is refused until retried. When personal TUI
1136
+ activity overtakes a hub prompt, Pi is detached: a prompt the extension proves it
1137
+ never inserted returns to the queue, anything else is held as `needs_review`.
1138
+ It leaves queued and held deliveries, and existing manual or budget pauses,
1139
+ untouched. The queue listing names `off roster` as the membership hold. Returning
1140
+ and starting the peer makes retained queued messages available again; held
1141
+ uncertain work still needs the existing queue resolution command. A detached
1142
+ personal Pi TUI with a live owner still blocks controlled recovery as `pi is not
1143
+ settled`; end that retained TUI before restart/upgrade. The hub does not declare
1144
+ a live native owner settled or close it implicitly during preparation. Open owner and
1145
+ reviewer work, including ownership of `in_review` tasks, is offered through the
1146
+ existing reassignment path; a transferred review keeps its review state. If nobody can
1147
+ take it, its assignment stays and a notice names the person's next action. Task
1148
+ text in a notice uses its public title, so a private task remains a stub. A stop
1149
+ that is unconfirmed leaves the roster saved and reports that permission reset and
1150
+ handoff were not attempted; reapply the removal after checking the runtime.
1151
+
1152
+ A hub task, verdict, review or budget message addressed to an off-roster peer
1153
+ stays in its retained queue, with one public notice to the person. Task operations
1154
+ use the current owner and reviewer after reassignment. A mixed addressed audience
1155
+ receives the on-roster copies now and retains the off-roster copies; the sender
1156
+ sees the existing notice field (or a decision note for native answers). Broadcasts
1157
+ exclude off-roster peers; a person or agent addressing only removed peers is
1158
+ refused before publishing. The dashboard roster undo has its own peer-id
1159
+ confirmation and optional active-turn stop checkbox.
1160
+
1161
+ Without a roster setting, participation keeps the previous defaults. An explicit
1162
+ `roster.pi` overrides `pi.enabled`; otherwise that legacy switch continues to
1163
+ control Pi starts. External peer ids remain governed by their existing admission
1164
+ rules. A runtime permission override is cleared on removal and the configured
1165
+ default governs the next attachment. Config file edits outside the authorized
1166
+ roster setting do not change running participation: they take effect at the next
1167
+ hub start. The tracked config can provide defaults and config.local.json can
1168
+ override them.
1169
+
999
1170
  ## Settings from the dashboard and the terminal
1000
1171
 
1001
1172
  The dashboard's Settings section and `ahub settings` show and change the same
@@ -1016,7 +1187,7 @@ ahub ui --settings # dashboard with a 15-minute settings session
1016
1187
  | --- | --- | --- | --- |
1017
1188
  | Permissions | `permission.<peer>` (the mode now) | the running hub only | at once |
1018
1189
  | Permissions | `permission_modes.<peer>` (the mode at hub start) | `config.local.json` | next hub start |
1019
- | Start | `peers.pi.start_mode`, `peers.codex.start_mode` (`tui` or `headless`) | `config.local.json` | that peer's next start |
1190
+ | Start | `peers.pi.start_mode`, `peers.codex.start_mode`, `peers.kimi.start_mode` (`tui` or `headless`) | `config.local.json` | that peer's next start |
1020
1191
  | Start | `pi.auto_start` | `config.local.json` | next hub start |
1021
1192
  | Routing | `routing.stay_switch`, `routing.classes.<class>.peers`, `.escalate_to`, `.route`, `.pi_backend` | `routing.local.toml` | at once |
1022
1193
  | Switches | `research.enabled`, `approvals.notify`, `snapshots.enabled`, `coordination` | `config.local.json` | next hub start |
@@ -1070,7 +1241,7 @@ A peer that has a TUI the hub attaches to starts in it by default (issue #269).
1070
1241
  | pi | `tui` | `ahub pi --headless` (or `--mode headless`), or `peers.pi.start_mode: headless` |
1071
1242
  | codex | `tui` (`ahub codex`) | `peers.codex.start_mode: headless`: a hub-made start runs the app-server only |
1072
1243
  | claude | `tui` (`ahub claude`) | none |
1073
- | kimi | headless (ACP) | it has no TUI the hub attaches to |
1244
+ | kimi | `tui`, pull-only (`ahub kimi`) | `ahub kimi --mode headless`, or `peers.kimi.start_mode: headless` |
1074
1245
  | local | headless (hub-native) | not applicable |
1075
1246
 
1076
1247
  - **You type the command:** `ahub pi` opens Pi's TUI in that terminal.
@@ -1102,6 +1273,53 @@ A peer that has a TUI the hub attaches to starts in it by default (issue #269).
1102
1273
  unplanned stop, a Pi that ran in a terminal is reported with its command and
1103
1274
  is not replaced by a headless one unless headless is its start mode.
1104
1275
 
1276
+ ### Kimi in its own TUI
1277
+
1278
+ `ahub kimi` runs Kimi in the person's terminal by default. The launcher atomically
1279
+ merges only `mcpServers["agent-hub"]` in `.kimi-code/mcp.json`, keeping foreign
1280
+ entries and fields. It contains machine paths and the peer identity, not a token.
1281
+ `ahub init` ignores that file when it is untracked; a tracked file is still written
1282
+ with a warning. `--print-command` shows the change and command without writing.
1283
+ The configured `kimi_cmd` must be a single executable or end in exactly `acp`;
1284
+ the TUI uses the executable or drops that final word. Other wrappers are refused
1285
+ with the headless command rather than guessed.
1286
+
1287
+ The TUI is pull-only. Its model reads `hub_inbox` at the start of work and before
1288
+ reporting, and shares results explicitly with `hub_send`. Status, the console and
1289
+ the dashboard show `pull-only`, the waiting count and the last inbox read. Messages
1290
+ and important markers do not push or interrupt it. There is no hub busy state,
1291
+ watchdog, console approval, hub permission mode, context reading, automatic quota
1292
+ pause/handoff, shared final answer or session resume. Read quota and approve tools
1293
+ in Kimi's own TUI; a person can pause the hub queue by hand. End the native terminal
1294
+ session there, not with `ahub stop kimi`.
1295
+
1296
+ Automatic routing never picks a pull-only owner or reviewer, even as the only
1297
+ candidate. A proposer can name the owner or claim its own task; a person or the
1298
+ conductor can name an owner or reviewer with
1299
+ `ahub task assign <id> kimi --role owner|reviewer`. A waiting task reserves its
1300
+ named owner; naming its reviewer is refused until dependencies are approved.
1301
+ A named review waits in the same inbox. Queue holds and pauses refuse a pull with
1302
+ the reason; an unaccepted assignment still follows the existing release deadline.
1303
+
1304
+ To switch to ACP, end the attached TUI and run `ahub kimi --mode headless`: the
1305
+ person's command removes only the hub's project MCP entry before starting ACP.
1306
+ A daemon-made headless start refuses a stale entry with that command and never
1307
+ edits the project file. To switch back, stop the headless peer with `ahub stop kimi`
1308
+ then run `ahub kimi --mode tui`. The peer id, queued messages and open tasks remain;
1309
+ the ACP session is not resumed in the TUI. Agents cannot switch modes.
1310
+
1311
+ Projects with no explicit Kimi start mode also move to this default on upgrade.
1312
+ The coordinating upgrade command announces it once; to keep ACP, run
1313
+ `ahub settings set peers.kimi.start_mode headless`.
1314
+
1315
+ Source preflight checked Kimi Code 2.1.1 at
1316
+ [f67e6398](https://github.com/MoonshotAI/kimi-code/tree/f67e6398fb3210ad8ace970e2dfd5bcc984ed61f):
1317
+ trusted ACP workspaces read the user, repository-root and project MCP files, and a
1318
+ passed session entry connects beside the project entry. Its model request path
1319
+ uses tool definitions and managed AGENTS instructions, not MCP initialize
1320
+ instructions. Folder trust, real TUI tool discovery and the model round trip are
1321
+ still unverified live; see `docs/smoke.md`.
1322
+
1105
1323
  ### Migration from 0.12.22 and earlier
1106
1324
 
1107
1325
  Pi's default changes from headless to its TUI.
@@ -1354,8 +1572,8 @@ can run again), unless the error says the state cannot be read (a damaged
1354
1572
  `hub.db` or journal fails the same way every time): `ahub reset --all --yes`
1355
1573
  archives such a state directory as it is. A full reset names the archive once
1356
1574
  the state directory has moved.
1357
- It never touches claude-mem: notes saved with `hub_remember` are shared memory,
1358
- not hub state. Claude Code sessions attached to the hub lose their hub session;
1575
+ It never touches claude-mem or hub memory (`~/.agenthub/memory/`): notes saved with
1576
+ `hub_remember` are shared memory, not hub state. Claude Code sessions attached to the hub lose their hub session;
1359
1577
  relaunch them with `ahub claude`.
1360
1578
 
1361
1579
  ## Orphaned daemons
@@ -1401,21 +1619,21 @@ section is what they run.
1401
1619
 
1402
1620
  Upgrade running projects with the target release's own coordinator. It accepts
1403
1621
  a running source on control protocol 9 (0.6.x), 10 (0.7.0 through 0.12.0),
1404
- 11 (0.12.1 and 0.12.2), 12 (0.12.3), 13 (0.12.4 through 0.12.15), 14 (0.12.16), 15 (0.12.17 through 0.12.19) or 16 (0.12.20 through 0.12.23), and only
1622
+ 11 (0.12.1 and 0.12.2), 12 (0.12.3), 13 (0.12.4 through 0.12.15), 14 (0.12.16), 15 (0.12.17 through 0.12.19) or 16 (0.12.20 through 0.12.25), and only
1405
1623
  a target on its own protocol, so the target's coordinator fits every supported
1406
1624
  source and carries every recovery fix released up to it. Protocol 8 and older
1407
1625
  (0.5.x and earlier) are refused as `manual-bootstrap-required`. Run from the
1408
1626
  project directory, without replacing the global CLI first:
1409
1627
 
1410
1628
  ```bash
1411
- bunx --package @staix/agent-hub@0.12.23 ahub upgrade --to 0.12.23 --dry-run
1412
- bunx --package @staix/agent-hub@0.12.23 ahub upgrade --to 0.12.23 --yes
1629
+ bunx --package @staix/agent-hub@0.12.25 ahub upgrade --to 0.12.25 --dry-run
1630
+ bunx --package @staix/agent-hub@0.12.25 ahub upgrade --to 0.12.25 --yes
1413
1631
  ```
1414
1632
 
1415
1633
  | Running now | Coordinator to use |
1416
1634
  | --- | --- |
1417
1635
  | 0.6.x (protocol 9) | the target's, through `bunx` as above |
1418
- | 0.7.0 through 0.12.0 (protocol 10), 0.12.1 and 0.12.2 (protocol 11), 0.12.3 (protocol 12), 0.12.4 through 0.12.15 (protocol 13), 0.12.16 (protocol 14), 0.12.17 through 0.12.19 (protocol 15), 0.12.20 through 0.12.23 (protocol 16) | the target's, through `bunx` as above |
1636
+ | 0.7.0 through 0.12.0 (protocol 10), 0.12.1 and 0.12.2 (protocol 11), 0.12.3 (protocol 12), 0.12.4 through 0.12.15 (protocol 13), 0.12.16 (protocol 14), 0.12.17 through 0.12.19 (protocol 15), 0.12.20 through 0.12.25 (protocol 16) | the target's, through `bunx` as above |
1419
1637
  | any supported source, with the installed CLI already at the target | `ahub upgrade` below, which is the same coordinator |
1420
1638
  | 0.5.x or earlier (protocol 8 and older) | not supported: bootstrap by hand with the matching CLI |
1421
1639
 
@@ -1447,14 +1665,14 @@ projects first:
1447
1665
 
1448
1666
  ```bash
1449
1667
  ahub restart --dry-run
1450
- ahub upgrade --to 0.12.23 --dry-run
1668
+ ahub upgrade --to 0.12.25 --dry-run
1451
1669
  ```
1452
1670
 
1453
1671
  Apply only after reviewing the plan:
1454
1672
 
1455
1673
  ```bash
1456
1674
  ahub restart --yes
1457
- ahub upgrade --to 0.12.23 --yes
1675
+ ahub upgrade --to 0.12.25 --yes
1458
1676
  ahub recovery status [<operation-id>]
1459
1677
  ahub recovery resume [<operation-id>]
1460
1678
  ahub recovery abort [<operation-id>]
@@ -2092,15 +2310,22 @@ include the stamped ancestors (CI checks out full history).
2092
2310
  During release preparation, source review precedes restamping. Review each stale
2093
2311
  page against its covered source, correct drift, and use the full SHA of the
2094
2312
  reviewed source commit as `verifiedAgainst`. Record any deferred page and its
2095
- specific unverified claims in the release verification report before tagging.
2313
+ specific unverified claims in the release verification report before tagging. Deferred
2314
+ pages must still be source-reviewed and current; a deferral is not a stale-stamp waiver.
2315
+ The tag gate runs `node scripts/check-docs.mjs --require-fresh` with full history
2316
+ before publishing. Stale or nonancestor stamps refuse publication, with the
2317
+ release merge-commit instruction; an identical tree and green CI cannot waive this.
2318
+
2096
2319
  Do not advance a stamp solely to clear a notice. Source stamps can name an
2097
2320
  ancestor: the manifest-only follow-up commit need not hash or stamp itself.
2098
2321
 
2099
2322
  ## Seeded guard verification
2100
2323
 
2101
- `bun scripts/seeded-check.ts` runs six guard pairs sequentially: header quoting,
2102
- Origin refusal, control-token authentication, the hop cap, PII public views and
2103
- uncertain-delivery receipts. Each named test first passes on current tracked
2324
+ `bun scripts/seeded-check.ts` runs every guard pair in `scripts/seeds.json`
2325
+ sequentially, starting with header quoting, Origin refusal, control-token
2326
+ authentication, the hop cap, PII public views and uncertain-delivery receipts.
2327
+ A guard needs a test that runs on Linux, where the CI job runs; a macOS-only
2328
+ protection (sandbox, text projection) is covered by its regression test. Each named test first passes on current tracked
2104
2329
  checkout bytes, then must fail an assertion with the corresponding guard weakened.
2105
2330
  Seed rot (anything other than one exact replacement), a surviving seed and an
2106
2331
  invalid detection have distinct errors. Compiler, setup, unrelated-test and timeout
@@ -2116,8 +2341,8 @@ fixture location with test and leak evidence for inspection.
2116
2341
 
2117
2342
  The required Linux CI job `seeded guards` follows the ordinary checks; it does not
2118
2343
  repeat on macOS or run recursively inside `bun test`. The runner reports every
2119
- pair's elapsed seconds and the total runtime. Runtime measurement remains pending
2120
- until that gate executes; a green ordinary check alone does not prove these pairs.
2344
+ pair's elapsed seconds and the total runtime. A green ordinary check alone does
2345
+ not prove these pairs.
2121
2346
 
2122
2347
  The full CI gate tests the PR head tree on Linux and macOS, followed by the
2123
2348
  sequential seeded-guard job. Main and release jobs reuse only a successful full
@@ -2126,6 +2351,9 @@ unreadable result runs the main gate again and refuses release. A manual
2126
2351
  `prepare_bundle` dispatch builds reviewable plugin assets without publishing;
2127
2352
  it is never accepted as full-gate evidence. A `timing_runs=20` dispatch runs only the daemon, PII screen and ACP
2128
2353
  test files twenty times on macOS, in its own concurrency group; it does not replace the full gate.
2354
+ `scripts/check.sh` stops a suite still running after `AHUB_CHECK_HANG_S` seconds
2355
+ (600 by default); hosted macOS CI sets 780 inside the unchanged 15-minute job
2356
+ limit (#378).
2129
2357
 
2130
2358
  ## Preview initialization and native launch
2131
2359
 
@@ -2296,3 +2524,422 @@ prompt was accepted but before history was persisted is not treated as empty:
2296
2524
  its delivery is held, and another start refuses until resume history is verified.
2297
2525
  Inspect and settle the held delivery before deliberately replacing that unpersisted
2298
2526
  session by restarting the hub; the stop never silently chooses a fresh session.
2527
+
2528
+ A pull-only Kimi TUI has no controlled restore or resume. While it is attached,
2529
+ upgrade/restart planning stops before effects and asks the person to end Kimi in
2530
+ that terminal and make a new plan. Headless Kimi restoration stays headless even
2531
+ though the unset launch mode now means TUI; older targets keep their legacy
2532
+ command without a mode flag. Native recovery remains unverified.
2533
+
2534
+ Changing a reviewer on a task in review withdraws unread requests and tells the
2535
+ former reviewer its request is withdrawn. A delivered request cannot be recalled,
2536
+ but a later verdict from that former reviewer is refused by current authority.
2537
+
2538
+ Legacy Claude pull-only sessions retain their existing automatic owner/reviewer
2539
+ selection; the watched-Kimi exclusion does not disable that review path. After
2540
+ first creating the Kimi MCP file, run `ahub init` to ignore the untracked file.
2541
+ Init leaves existing ignore bytes alone when no Kimi MCP file exists.
2542
+ ## Scoped grants for instruction files
2543
+
2544
+ `ahub settings set scoped_grants.protect_instructions true` asks a person before
2545
+ Pi/local scoped writes and edits to `AGENTS.md`, `CLAUDE.md` and `QWEN.md`, and
2546
+ withholds automatic permission from the managed Claude hook. Case, compatibility
2547
+ forms and both symlink spellings are checked. The default is false: these project
2548
+ documents remain editable under scoped grants. Reads, explicit approval and
2549
+ never-ask keep their existing behavior.
2550
+
2551
+ Use `ahub settings preview scoped_grants.protect_instructions true` before a
2552
+ change and `ahub settings undo` to restore it. It is in the Permissions registry,
2553
+ writes only machine-local `protect_instruction_files`, and applies immediately
2554
+ in the running hub. A dashboard settings session may change it; an ordinary
2555
+ session may turn protection on but cannot weaken it. No agent surface changes it.
2556
+ Like other machine-local security defaults, loading it requires git to establish
2557
+ that the file is untracked; a dropped value is reported by the settings result.
2558
+
2559
+ ## SDLC artifact receipts and gates
2560
+
2561
+ The initial #257 lifecycle is off without .agenthub/sdlc.toml. Advise shows blockers; enforce checks head-bound review and approval transitions. See [the SDLC contract](sdlc.md) for the fixed stage order, required check names, claimed local receipts, console-only readbacks and pending custom/release/live parts. Owners/reviewers record bounded identities through hub_sdlc_record; these grant no additional authority.
2562
+ ## Optional Qwen Code peer
2563
+
2564
+ Select Qwen per project with `ahub roster add qwen`; it defaults off and is absent
2565
+ from default class preferences. `ahub qwen [--mode headless] [--model <alias>]`
2566
+ starts its ACP peer. `--print-command` previews; TUI is refused until #286's
2567
+ verification. `ahub stop qwen` stops the owned process group. A conductor may start
2568
+ it only through the selected roster and existing capabilities.
2569
+
2570
+ The supported native ACP identity is qwen-code 0.25.0. A CLI version label alone
2571
+ is insufficient: startup verifies its native identity/version and advertised mode
2572
+ ids before any prompt. The observed local installation reports CLI 0.25.0 while
2573
+ its package/ACP source says 0.24.1; do not call that installation ready. Configure
2574
+ `qwen_cmd` only in untracked config.local.json with a verified 0.25.0 executable.
2575
+ The provider's tunnel/relay, if needed, must already be available. Startup cannot
2576
+ prove network readiness from a version command.
2577
+
2578
+ Modes: ask maps to default, scoped frequency maps to auto-edit, never-ask maps to
2579
+ yolo. Qwen yolo approves every tool outside any hub sandbox; its own vendor bounds
2580
+ apply. Auto and plan are not hub mode mappings. Unknown quota refusals are not
2581
+ classified as authoritative quota; until a real pinned refusal is recorded, pause
2582
+ by hand. Occupancy is context with a source, never a consumption estimate. Roles
2583
+ do not establish that Qwen can reliably replace Kimi before the live leg.
2584
+
2585
+ Qwen controlled recovery and automatic crash resume load the recorded conversation with ACP session/load. The emitted launcher passes --session-id; a controlled plan with a missing or unsafe identity refuses before effects. Preview redacts the id. A custom executable argv keeps its wrapper arguments before appended model flags. Native recovery remains unverified.
2586
+
2587
+ ## Optional Jcode peer
2588
+
2589
+ Use ahub roster add jcode, then ahub jcode --mode headless [--model <alias>] [--provider-profile <name>]. The person launcher configures only agent-hub-jcode in .jcode/mcp.json; run ahub init afterwards to ignore the untracked machine-path file. Conductor/dashboard starts read that entry without editing it. Preview starts nothing, and ahub stop jcode stops only the owned private daemon/ACP groups. jcode_cmd, jcode_home and jcode_provider_profile are machine-local and never editable from settings.
2590
+
2591
+ Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or runtime mode mapping is invented. Quota and consumption remain unknown. Version 0.94.0 cannot prove native session/load identity, so attached Jcode blocks controlled recovery before effects and crash recovery asks for deliberate native reopening. A requested load without an echoed identity refuses; no fresh session is presented as restored. Provider/tool/native teardown receipts remain unverified in the pinned contract report.
2592
+
2593
+ # Headless ACP watch (#286)
2594
+
2595
+ - A person opens `ahub watch kimi` or `ahub watch qwen` in a second terminal. `--no-thoughts` hides thought items; `--color=auto|always|never` controls colour. `q` or Ctrl+C leaves the view, keeping the peer running. Answer approvals in `ahub console` or with `ahub permit`.
2596
+ - Watch replays bounded memory history from this daemon, then displays live updates. It is the hub's read-only view, with no prompt input. It does not read native session files.
2597
+ - Kimi's default is its own pull-only TUI (#316). Watch requires `ahub kimi --mode headless`; its own TUI remains visible in its native terminal. Qwen requires roster participation and verified ACP 0.25.0. `ahub qwen --mode tui` remains refused.
2598
+ - Protocol stays 16; a same-protocol older daemon answers the new request as unknown, which the CLI reports. No automatic pane opening is included in this slice.
2599
+ - Native T0 limits: [ACP watch verification](verification/2026-10-11-acp-watch-t0.md).
2600
+
2601
+ # gsd-lite lifecycle guidance (#257)
2602
+
2603
+ - Set `workflow = "gsd-lite"` in `.agenthub/sdlc.toml` for the next daemon start; default none preserves the existing flow. Mode advise displays checklist blockers without blocking, while enforce checks them at approval.
2604
+ - The task reviewer/person records phase criteria via `ahub sdlc record <id> '<receipt JSON>'`. Existing tasks and predecessor ids must match the board; import does not move owners or edit dependencies. Use the existing task propose `--after` command to create edges.
2605
+ - `ahub sdlc status <id>`, `explain <id>` and `export <id>` read the same current board/config projection. Export hashes are projection/config hashes, with no external text, extra authority or verification claim. Schema and example: [SDLC](sdlc.md#gsd-lite-checklist-guidance).
2606
+
2607
+ # Catalog session guidance (#295)
2608
+
2609
+ - Read available guidance with `ahub role list [--group dev|research]` and `ahub role show <id>`. Each definition identifies its layer and content hash. Doctor reports invalid files/selections without printing their contents.
2610
+ - Select up to two ids per peer in `catalog_roles` in the shared/local config, with at least one flow base already held by that peer. Empty local lists clear shared selections. This initial slice applies selections at a new daemon/MCP/adapter start; live assignment/settings and task roles follow separately.
2611
+ - Defaults preserve the existing flow. Catalog guidance adds no authority or routing preference. Native ingestion/retention and measured benefit remain unverified. Schema, bounds and source notice: [roles](roles.md).
2612
+
2613
+ # Project profiles (#259)
2614
+
2615
+ - Initialize new projects with `ahub init --profile research|writing|general`; default dev retains its existing templates and contracts. Profile aliases map to the existing base flow and are displayed beside it.
2616
+ - Non-dev plans declare paths, section anchors, source ids and claims. Configure completion checks explicitly in machine-local config; selecting a profile never starts a check or study. Schema, examples and pending converter/policy slices: [profiles](profiles.md).
2617
+
2618
+ # Private and read-only data paths (#259)
2619
+
2620
+ - Optional pii.paths forces matching declared refs/plans/section files to the on-prem flow before triage and memory, including when ordinary pattern routing is off. Optional data.readonly protects managed local/Pi writes and makes managed commands filesystem read-only.
2621
+ - Both lists are empty by default and apply at daemon start. Reads/stdout remain available; command-created files/caches are blocked in read-only mode. Exact path rules, alias handling and evidence: [data policy](data-policy.md).
2622
+
2623
+ # Rich-document text projections (#259)
2624
+
2625
+ - Configure text_projection only in an untracked machine-local file, with a separate {input} argv argument. Facts uses bounded read-only/no-network conversion from a scratch directory, where the converter reads only its input snapshot and its own program and script files (no other project file, even under `local.read_allow`), and a content/config cache; failure keeps the prior file view and logs a bounded notice, and a conversion that failed with its full deadline is not retried for the same bytes and command for the life of the hub process (a bounded in-memory record) (#382).
2626
+ - Raw change identity and projected presentation stay separate; private paths never enter conversion. Schema, limits and current surface scope: [text projections](text-projection.md).
2627
+
2628
+ # Task catalog guidance (#295)
2629
+
2630
+ - A proposal may name `role` from `ahub role list`. The allowed class list is checked in Tasks, and assignment/review notices carry bounded guidance. The role grants no authority and changes no routing decision. Scope and pending person-assignment surfaces: [roles](roles.md).
2631
+
2632
+ # Person catalog-role assignment (#295)
2633
+
2634
+ - Use `ahub role assign <peer> <id>` or `ahub role clear <peer> [<id>]`, or the dashboard Roles settings group. The selection is bounded to two compatible catalog ids, writes only machine-local settings and applies at the next peer start. Inherit and explicit no roles are distinct.
2635
+ - Change an open task's guidance with `ahub task role <id> <role|none>`. Agent shells and peer/tools control clients cannot use these mutation commands. Details and unconfirmed native consumption: [roles](roles.md).
2636
+
2637
+ # Document projection review and undo
2638
+
2639
+ - Machine-local text_projection also supplies bounded review and reverse undo previews from stored raw snapshots. Task-proposal baselines survive restart and reviewer changes; missing/private/pruned evidence is unavailable. See [text projections](text-projection.md) for caps and converter requirements.
2640
+ - Undo remains a raw-file operation: projected text cannot bypass later-edit, concurrency or unknown-turn refusals. Native model/account ingestion remains unverified.
2641
+
2642
+ # Opt-in shadow repository
2643
+
2644
+ - `ahub init --profile research|writing|general --shadow [--dry-run --json]` supplies hub-owned snapshot/facts/undo storage for a non-git folder. It creates no `.git` entry and never switches an existing Git project.
2645
+ - Maintain `.agenthub/ignore` for large/raw data. Snapshot and facts operations leave the shadow index/HEAD alone; raw undo refusal rules remain authoritative. Shadow metadata stays protected from managed worker writes. See [profiles](profiles.md).
2646
+
2647
+ # Per-project profile data
2648
+
2649
+ - Use `profile_overrides` for class aliases, supported plan selection, role guidance, catalog defaults, managed AGENTS content and advisory example checks. Shared/local maps merge by key; selections/text replace. See [profiles](profiles.md).
2650
+ - Refresh instructions with init and restart the daemon/MCP clients to apply their resolved contracts. Existing flow-role and executable-check authority remains in `roles`/trusted `checks`. Native model/account evidence remains unverified.
2651
+
2652
+
2653
+ ## Staging work in Backlog (#263)
2654
+
2655
+ Use `ahub task propose implement "Later work" --backlog --owner codex` to stage
2656
+ work without routing it. The owner is a reservation, including when an agent
2657
+ names itself. Normal proposal behavior is unchanged without `--backlog`.
2658
+
2659
+ The person inspects `ahub board backlog` and `ahub task show <id>`, then runs
2660
+ `ahub backlog pull <id>` to put it in To Do. Dependencies still block assignment.
2661
+ Ready work uses the existing assignment and delivery-recovery contract; if no
2662
+ peer can take it, a later attachment or restart can offer it. Return ownerless
2663
+ To Do work with `ahub backlog return <id>`. Owned or started work cannot return.
2664
+
2665
+ Ordinary agent task lists and conductor task reads exclude Backlog. Staged work
2666
+ is never claimed, accepted, completed, swept, escalated or relayed. PII cards and
2667
+ notices use the existing public stub. Planner grooming, five-column views, releases and dates are described below.
2668
+ The native planner/two-release smoke remains unverified; board release actions
2669
+ never tag or publish software.
2670
+
2671
+
2672
+ Pulling Backlog establishes its first execution-proposal boundary for projected
2673
+ review snapshots and research records. An initial Backlog row is not an offered
2674
+ proposal. Research uses the first pull time and preserves identity across later
2675
+ unstarted return/pull cycles; a new backlogged id after reset starts a new record
2676
+ generation. Partial work with acceptance/check/review evidence cannot return to
2677
+ Backlog even after decline or reassignment leaves it ownerless.
2678
+
2679
+
2680
+ ## Dashboard project board (#263)
2681
+
2682
+ The board displays Backlog, To Do, In Progress, Review / QA and Done from task
2683
+ states. To Do separates ready work from dependency, reservation, delivery-hold
2684
+ and unavailable-owner waits. Review and Done offer no flow dragging. Owner and
2685
+ reviewer names remain readable beside their filled/outlined color markers.
2686
+ Urgent tasks display P0 and a star; ordinary legacy tasks display P2.
2687
+
2688
+ The legend reads the same live peer status as `ahub status`, with a derived
2689
+ owned-work count, active board ids and explicit permission display. Use the agent
2690
+ filter or By agent lanes to inspect work. Done shows recent rows first, with
2691
+ older rows expandable. At phone width columns stack and controls remain usable.
2692
+
2693
+ Drag eligible work onto a peer to assign it, or use its labelled select and
2694
+ Assign button. Drag Backlog into To Do to pull it; return only ownerless To Do
2695
+ work to Backlog. Each move has a button/keyboard equivalent and reaches `Tasks`
2696
+ through the existing authenticated console/dashboard action path. Cards carry
2697
+ origin, project, instance and view-generation fences; stale or foreign drags
2698
+ are refused. Review/verdict/approval transitions stay with their flow actors.
2699
+
2700
+ A hub advertises Backlog support explicitly. Older or unknown snapshots cannot
2701
+ silently turn Add to Backlog into an immediate offer. PII cards retain their
2702
+ public stub; legend entries contain ids/counts, never task prose. Planning priority/rank, releases, dates, planner grooming/undo and GitHub import
2703
+ are described below. Native planner-cycle evidence remains unverified.
2704
+
2705
+
2706
+ ## Planning and phased releases (#263)
2707
+
2708
+ Use `ahub backlog list` to read public staged work, then `ahub backlog plan <id>
2709
+ <revision> <fields-json> <reason>` to set rank, priority (0-3), release id, planned
2710
+ start/due UTC milliseconds or pin. `pin` accepts true/false; `undo` needs the
2711
+ current revision and latest eligible edit. The dashboard provides local-time
2712
+ date fields, task/release filters and lanes, and Reload current values when an
2713
+ edit is stale. A person's order, pins and frozen scopes protect planner changes.
2714
+
2715
+ Create a phase with `ahub release new <name> <goal> <order>`, inspect `list` or
2716
+ `show`, and set planned start/cut/ship with `plan <name> <revision> <dates-json>`.
2717
+ `activate`, `freeze`, `ship` and `drop` need its current revision. Only a person
2718
+ freezes, ships, drops or edits frozen scope. Ship records the first ship time
2719
+ only after every member is approved or moved out; it runs no tag or publish.
2720
+ The dashboard shows phase progress, blocking dependencies, dates and remaining
2721
+ work. Actual task dates come from execution/review/approval history, never input.
2722
+
2723
+ Configured planners read `hub_backlog_list` and `hub_release_list`, edit with
2724
+ `hub_backlog_plan`, and undo their own latest eligible change with
2725
+ `hub_backlog_undo`. Catalog guidance or a caller-supplied role grants no authority.
2726
+ PII cards stay stubs, reasons are screened/withheld in public history, and planning
2727
+ telemetry records ids/changed fields without prose. #247 task records carry
2728
+ optional release, priority, plannedStart and due, retaining unknown legacy data.
2729
+
2730
+ Dependency/reservation planning, split/pull WIP limits, batched incoming notices
2731
+ and one-way GitHub import are described below. Source checks are recorded in the
2732
+ release verification report. Native planner work across two releases remains
2733
+ unverified; source and fixture checks do not establish installed live behavior.
2734
+
2735
+ Office merge corrections retain the header's view selector when Off hides the
2736
+ scene. Activating a card reveals its task if a state filter excluded it; Work
2737
+ includes rework. Stable desk slots determine bounds after peers disconnect.
2738
+ Reduced motion removes departures immediately and the existing snapshot poll
2739
+ prunes transient deadlines without new timers. Explicit unattributed turns have
2740
+ no guessed task bubble. Warning caps retain conflicts first and parallel warning
2741
+ kinds have separate segments/labels. Physical visual validation remains pending.
2742
+
2743
+
2744
+ Planner backlog plans also accept `deps` (at most 64 unique task ids) and
2745
+ `reserved` (rostered peer id or null). Dependency/reservation edits require
2746
+ unstarted, unowned backlog work even for the person; cycles and missing ids
2747
+ are refused before persistence. Planning undo restores previous dependency and
2748
+ reservation values at the same revision fence. Editing never routes work.
2749
+
2750
+
2751
+ Release date editors invalidate stale revisions and offer Reload current release
2752
+ without overwriting unsaved dates. Project changes clear release creation drafts.
2753
+ Dashboard release actions use public numeric ids even when labels are withheld;
2754
+ `ahub release show <name>` looks up the stored identity on the console and returns
2755
+ the screened public projection. Exact-head source verification is recorded in the release report.
2756
+
2757
+
2758
+ ## Planner WIP pull (#263)
2759
+
2760
+ `hub_backlog_pull` takes id, current planning revision and a bounded reason. A
2761
+ configured planner with assignment capability reserves a ready To Do slot using
2762
+ current routing, roster, class, quota and health constraints. It refuses pins,
2763
+ unapproved dependencies, frozen scope and overriding person P0 order/reservations.
2764
+ The person uses `ahub backlog pull-ready <id> <revision> <reason>` or Pull within
2765
+ WIP on a card. Explicit manual pull/assignment retain their existing authority.
2766
+
2767
+ Capacity defaults to one per peer. `ahub settings set tasks.wip_limits.codex 2`
2768
+ uses the existing machine-local registry path; integers 0..32 apply at hub start,
2769
+ with 0 disabling planner admission for that peer. Stored pending values and
2770
+ effective runtime limits remain distinct. Status and the agent legend count
2771
+ owned unfinished work plus unowned planner-pull reservations.
2772
+
2773
+ Pending unowned, unstarted pull can be undone at its latest owned revision via
2774
+ `hub_backlog_undo` or the existing planning undo control, restoring its earlier
2775
+ reservation. An ordinary return to Backlog also restores the pre-pull reservation unless a later explicit reservation edit superseded it. Normal release routing offers work only while that reserved peer
2776
+ still has capacity; no other peer inherits its slot. Split and one-way import are described below. Native verification remains
2777
+ outstanding; exact-head source checks are recorded separately.
2778
+
2779
+
2780
+ Planned-date editors preserve loaded UTC milliseconds until their displayed
2781
+ value changes, including repeated local wall times during a clock change. Local
2782
+ inputs retain seconds/milliseconds and support HTML date years without truncating
2783
+ fields; see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#local-dates-and-times.
2784
+ Date-editor source proof is recorded with the exact-head checks.
2785
+
2786
+
2787
+ ## Backlog split (#263)
2788
+
2789
+ Use `hub_backlog_split` with parent id/revision, reason and two to eight part
2790
+ objects, or `ahub backlog split <id> <revision> <parts-json> <reason>`. Each part
2791
+ has a title and optional detail/class/refs/plan; `after` names existing ids and
2792
+ `afterParts` names earlier zero-based parts. The selected task's dashboard Split
2793
+ form accepts one title per line and optional sequential dependencies.
2794
+
2795
+ The original card remains integration/acceptance work and waits for every part.
2796
+ Children retain prerequisite, privacy and phase planning. A person's P0 order
2797
+ permits that goal's required predecessors, preventing dependency deadlock.
2798
+ Unused unchanged backlog children can be removed by latest split undo; later
2799
+ edits, execution, ownership or outside references refuse it. All writes roll
2800
+ back together and observers receive changes only after commit. Exact-head source checks are recorded separately; native verification remains
2801
+ unverified.
2802
+
2803
+
2804
+ The manager allows split screening, the bounded database wait and forwarding margin before declaring a missing reply unconfirmed. Reload the task before retrying an unconfirmed split. Stored role ids survive unavailable catalog guidance. Task memory-reference markers do not supersede assignment or check results, and dependency recovery ignores them.
2805
+
2806
+ ## One-way GitHub intake (#263)
2807
+
2808
+ `ahub board import github --label <label> [--milestone <milestone>]
2809
+ [--repo <owner/repo>]` is person-only. Omitted repo is resolved by gh in the
2810
+ project directory. The command reads open issues with fixed bounded argv and
2811
+ stages up to 32 into unoffered Backlog, retaining canonical repo/issue identity
2812
+ across restarts. Repeating intake does not refresh or overwrite existing cards.
2813
+
2814
+ The response lists confirmed imported/existing task ids and explicit partial,
2815
+ complete and unconfirmed state. A truncated page, time budget or interrupted
2816
+ staging is incomplete; repeat safely to reconcile the persisted identity.
2817
+ Public cards link to their source; PII cards expose no external identity.
2818
+ GitHub comments/labels/assignment/closure are never written. Exact-head source checks are recorded separately. Native verification remains
2819
+ unverified; no live account import was performed.
2820
+
2821
+
2822
+ `ahub board --columns` groups the same state-derived columns and ready/waiting
2823
+ reasons as the dashboard; `--release <name> | --release-id <id>` filters public rows on the hub.
2824
+ `--columns --json` returns filtered tasks and column metadata together. Ordinary
2825
+ peer reads retain the existing backlog prohibition. Phase views flag public ids
2826
+ approved after a known cut outside that release, and separately list unknown
2827
+ approval times without inventing dates. Exact-head source verification is recorded in the release report.
2828
+ ## Global attention and prompt output (#280, phase 3)
2829
+
2830
+ `ahub pet` reads the selected project's status file without a control token or
2831
+ network connection. It accepts only structural counts/state/first metadata from
2832
+ a confirmed daemon owner. Missing, malformed, legacy or unconfirmed data is
2833
+ reported as unavailable; it is not an empty live hub. `ahub pet --short` writes
2834
+ `ahub!N` when a known action count is positive, otherwise no bytes, including no
2835
+ newline. Explicit `pet` reads remain available when the presentation is off;
2836
+ normal `ahub status` appends the line only while the project's pet is enabled.
2837
+
2838
+ An open recovery lock is read without coordinating the operation. Only the
2839
+ shared runner check's observed absence adds an action; unknown remains watch and
2840
+ is labelled unknown. A matching daemon recovery watch is replaced once, without
2841
+ double counting. A missing hub status is labelled unavailable even when a known
2842
+ recovery action can be shown. The output never resumes, aborts or disposes a run.
2843
+
2844
+ Person-reviewed tasks contribute review actions; an offline peer holding
2845
+ unfinished work contributes one watch item with its lowest task id. The console
2846
+ receives those structural facts through its existing authenticated status reply.
2847
+ `n` selects an exact visible review task, or prints the task/review guidance if
2848
+ that row is unavailable. Offline guidance names status/task reads and an explicit
2849
+ assignment command. No command is executed by navigation. There is no extra
2850
+ console poll, timer or task-list request for stream mode.
2851
+
2852
+ Intentionally person-owned work is not an offline agent. Neither user nor hub
2853
+ creates an offline watch item, while person-reviewed tasks remain actionable.
2854
+ Status reads only the board's structural id/state/owner/reviewer projection and
2855
+ reuses it for retained peer ids, avoiding task body/plan/history decoding.
2856
+
2857
+ Planner reservations normalize the same lowercase peer syntax as owner arguments,
2858
+ reject reserved pseudo-peers and unknown unconfigured ids, and still enforce the
2859
+ roster. Returning unstarted ownerless work to Backlog joins the next planner
2860
+ notice batch without waiting for a restart.
2861
+
2862
+ Queued planner batches retain bounded ids-only backlog references and recheck
2863
+ the board at actual delivery. A batch containing pulled/removed work is discarded
2864
+ before reaching the planner; its remaining backlog ids join the next batch. This
2865
+ floor also applies during the legacy stale-notice delivery experiment. No task
2866
+ text is copied and no routing/ownership state changes.
2867
+
2868
+ ## Console character choices (#280)
2869
+
2870
+ `pet.character` selects stai (default), gyul, lantern, cursor-cat or boxbot.
2871
+ `pet.size` selects line (default), mini or full. Mini needs 100 columns; full also
2872
+ needs 40 rows, and smaller terminals fall back automatically. `P` cycles the
2873
+ built-ins and off for the current console only. `?` lists this under Pet, even
2874
+ while drawing is off. The command prompt keeps its original row and width.
2875
+
2876
+ `pet.glyphs` selects auto/ascii/blocks; unsupported locales and dumb/linux
2877
+ terminals retain the ASCII floor. `pet.blink:false` is static. Neither choosing
2878
+ nor drawing a character changes authority, config files, task state or polling.
2879
+ Explicit `ahub pet` and text status use the configured line face; prompt tokens
2880
+ remain character-independent. Native glyph width and tmux are unverified.
2881
+
2882
+ ## Dashboard attention character (#280)
2883
+
2884
+ The dashboard header draws the configured built-in character independently of
2885
+ Office. It uses the same structural needs model as status and the console. The
2886
+ accessible button names the character, state and action/watch counts; the tab
2887
+ title shows the action count. Activating the button scrolls and focuses the exact
2888
+ visible approval/task/peer row, or its related section with fixed id-only guidance
2889
+ when the row is filtered or unavailable. It performs no action and changes no
2890
+ filters. Legacy snapshots without attention keep the widget hidden.
2891
+
2892
+ Only a live approval alternates the two waiting poses once per second through
2893
+ CSS. `pet.blink:false` and reduced motion retain a static pose. No new timer,
2894
+ request, image protocol or character-file load is added. Project reset clears
2895
+ the widget and title. Native/browser visual validation remains unverified.
2896
+ With mini/full characters, active console notices remain visible away from the
2897
+ character: panel body rows show the bounded wrapped notice, and stream mode
2898
+ prints each fresh notice once through the existing local stream. Footer prose
2899
+ exclusion and fixed prompt/footer geometry remain. No new request or timer.
2900
+
2901
+ Automatic reroutes of planner-pulled work retain WIP and delivery-hold admission
2902
+ during offline, budget, roster and idle recovery. Explicit manual assignments
2903
+ retain their existing override authority.
2904
+
2905
+
2906
+ GitHub intake refuses comma-containing labels rather than allowing gh to split
2907
+ one literal label into several filters. WIP capacity excludes owner candidates
2908
+ only; eligible reviewers retain normal review routing. An auto-reassigning
2909
+ planner idle sweep waits without consuming its final step while no owner has
2910
+ capacity. Parent-only memory notes do not prevent unused child undo; child
2911
+ reference markers remain protected. Split-part plan schemas follow the selected
2912
+ project profile. Terminal tables preserve the visible read for stages and use
2913
+ a fresh peer status read on the same authenticated connection.
2914
+
2915
+ Integer WIP editors retain a saved pending value, including zero and inheritance, before hub restart. GitHub intake accepts dot-prefixed repository names within the existing bounded owner/repository identity. Split undo also refuses children referenced by another task's persisted phase checklist.
2916
+
2917
+ Declining rework returns changes_requested to To Do before rerouting. When a planner-pulled task has no eligible destination capacity, it remains ownerless in To Do and is retried after capacity clears, preserving the declined-owner exclusion.
2918
+
2919
+ With no release cut, outside approved tasks are reported under unknown cut evidence, including tasks with a known approval time. A child task execution budget also prevents split undo until the person disables that budget.
2920
+
2921
+ Split children retain their initial deterministic and inherited privacy signals across awaited screening. A routing-pattern reload cannot remove those captured signals from an unscreened child at final validation.
2922
+
2923
+ If a routing pattern adds deterministic privacy during screening, split history and telemetry use regex-private provenance rather than an earlier clear model result. The same captured final signals determine both the child and its provenance.
2924
+
2925
+ Dashboard backlog splits receive a dedicated outer HTTP request bound above manager forwarding, using the shared screening/database bounds and margin. Ordinary action policy remains unchanged. At phone widths, split form grids use one column so native date controls remain inside their panels.
2926
+
2927
+ An acknowledged ACP permission-mode change awaits queued cancellation cleanup only when the cancelled prompt response has already been observed. A still-unreported cancelled prompt stays busy under its existing deadline, while mode acknowledgements remain available. A successful mode acknowledgement alone does not prove the peer is idle.
2928
+
2929
+ Task idle sweeps ignore body-free memory-reference bookkeeping when finding the last real activity. Saving a task note or goal link does not postpone an idle notice or restart its escalation ladder.
2930
+
2931
+ Split reasons preserve deterministic privacy from both initial and final policy checks, including parent privacy. Once withheld, a reason stays withheld in public history even if routing patterns are later removed.
2932
+
2933
+ GitHub import rejects labels containing commas or double quotes before invoking gh, since its CSV-style label parser could otherwise select a different literal label.
2934
+
2935
+ Ask evidence skips body-free memory-reference markers when selecting the latest task transition and note. The selected note retains the existing withheld and on-campus privacy checks.
2936
+
2937
+ GitHub intake checks its staging deadline after every awaited proposal, including the final issue. A confirmed late save returns its task ID with partial=true and complete=false so the operator can read back and resume.
2938
+
2939
+ If GitHub intake saves a row but later bookkeeping fails, canonical identity readback preserves the confirmed ID and queues its Backlog notice. The response remains partial; unreadable or missing readback remains unconfirmed.
2940
+
2941
+ A later issue lookup or profile-preparation failure also returns the IDs confirmed earlier in the import as partial progress.
2942
+
2943
+ Release cut audits return exact counts with at most 32 example IDs per category; the dashboard states how many IDs are shown when truncated. Scope grouping and indexed approval dates avoid scanning each task history for every release. Full audit pagination remains a future extension.
2944
+
2945
+ Release cards include task states in their refresh key, so completion of an outside prerequisite updates blocked counts even when the release and audit preview are unchanged.