@staix/agent-hub 0.12.44 → 0.13.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.
- package/CHANGELOG.md +40 -0
- package/README.md +83 -116
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/docs/adding-an-ai-tool.md +102 -14
- package/docs/agent-notes/README.md +15 -0
- package/docs/agent-notes/adapters.md +63 -46
- package/docs/agent-notes/budget.md +7 -2
- package/docs/agent-notes/bus.md +6 -4
- package/docs/agent-notes/daemon.md +15 -8
- package/docs/agent-notes/local-worker.md +6 -4
- package/docs/agent-notes/tasks.md +18 -5
- package/docs/agent-notes/tests.md +11 -9
- package/docs/dogfood.md +92 -0
- package/docs/events.md +14 -1
- package/docs/operations.md +349 -26
- package/docs/profiles.md +2 -2
- package/docs/quickstart.md +12 -2
- package/docs/sdlc.md +61 -13
- package/docs/security.md +24 -12
- package/docs/smoke.md +9 -4
- package/docs/specs/2026-09-19-agent-hub-design.md +873 -13
- package/docs/verification/2026-10-19-reviewer-isolation.md +2 -0
- package/docs/verification/2026-10-21-469-r1-dashboard-tokens.md +43 -0
- package/docs/verification/2026-10-21-469-r2-dashboard-shell.md +54 -0
- package/docs/verification/2026-10-21-469-r3-dashboard-board.md +51 -0
- package/docs/verification/2026-10-21-469-r4-dashboard-views.md +77 -0
- package/docs/verification/2026-10-21-469-r6-dashboard-motion-states.md +82 -0
- package/docs/verification/2026-10-22-0.12.45.md +60 -0
- package/docs/verification/2026-10-22-code-facts.md +78 -0
- package/docs/verification/2026-10-22-codex-reviewer-isolation.md +47 -0
- package/docs/verification/2026-10-22-kimi-qwen-compat.md +79 -0
- package/docs/verification/2026-10-23-0.13.0.md +89 -0
- package/docs/verification/assets/469-r1-board-1440-dark.png +0 -0
- package/docs/verification/assets/469-r1-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r1-board-390-dark.png +0 -0
- package/docs/verification/assets/469-r1-board-390-light.png +0 -0
- package/docs/verification/assets/469-r2-agents-1440-dark.png +0 -0
- package/docs/verification/assets/469-r2-agents-768-dark.png +0 -0
- package/docs/verification/assets/469-r2-board-1024-light.png +0 -0
- package/docs/verification/assets/469-r2-board-1440-dark.png +0 -0
- package/docs/verification/assets/469-r2-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r2-board-390-dark.png +0 -0
- package/docs/verification/assets/469-r2-board-390-light.png +0 -0
- package/docs/verification/assets/469-r2-board-768-light.png +0 -0
- package/docs/verification/assets/469-r3-board-1440-dark.png +0 -0
- package/docs/verification/assets/469-r3-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r3-board-390-light.png +0 -0
- package/docs/verification/assets/469-r3-detail-1440-dark.png +0 -0
- package/docs/verification/assets/469-r3-detail-1440-light.png +0 -0
- package/docs/verification/assets/469-r3-detail-390-dark.png +0 -0
- package/docs/verification/assets/469-r3-plan-1440-light.png +0 -0
- package/docs/verification/assets/469-r3-plan-390-light.png +0 -0
- package/docs/verification/assets/469-r4-agents-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-agents-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-agents-390-dark.png +0 -0
- package/docs/verification/assets/469-r4-memory-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-memory-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-memory-390-dark.png +0 -0
- package/docs/verification/assets/469-r4-message-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-office-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-office-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-settings-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-settings-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-stream-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-stream-390-light.png +0 -0
- package/docs/verification/assets/469-r6-agents-empty-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-agents-empty-390-light.png +0 -0
- package/docs/verification/assets/469-r6-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-board-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-board-empty-1440-dark.png +0 -0
- package/docs/verification/assets/469-r6-board-empty-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-disconnected-1440-dark.png +0 -0
- package/docs/verification/assets/469-r6-disconnected-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-disconnected-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-skeleton-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-skeleton-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-toasts-1440-dark.png +0 -0
- package/docs/verification/assets/469-r6-toasts-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-toasts-390-light.png +0 -0
- package/docs/verification/dogfood/2026-10-22.md +3109 -0
- package/docs/verified.json +19 -16
- package/package.json +5 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +10120 -9623
- package/src/adapters/adapter-api.ts +2 -0
- package/src/adapters/agy/definition.ts +3 -1
- package/src/adapters/agy/entry.ts +5 -4
- package/src/adapters/claude-channel.ts +32 -12
- package/src/adapters/codex-appserver.ts +19 -2
- package/src/adapters/codex-review-isolation.ts +12 -5
- package/src/adapters/compat.ts +140 -0
- package/src/adapters/conformance/acp.ts +114 -0
- package/src/adapters/conformance/codex.ts +191 -0
- package/src/adapters/conformance/enrollment.ts +43 -0
- package/src/adapters/conformance/factories.ts +17 -0
- package/src/adapters/conformance/fake-paths.ts +12 -0
- package/src/adapters/conformance/fakes/acp-server.ts +267 -0
- package/src/adapters/conformance/fakes/acp-watchdog-agent.ts +10 -0
- package/src/adapters/conformance/fakes/app-server.ts +119 -0
- package/src/adapters/conformance/fakes/codex-bin.ts +15 -0
- package/src/adapters/conformance/fakes/jcode-agent.ts +91 -0
- package/src/adapters/conformance/fakes/model-server.ts +39 -0
- package/src/adapters/conformance/fakes/pi-rpc.ts +32 -0
- package/src/adapters/conformance/index.ts +11 -0
- package/src/adapters/conformance/kit.ts +50 -0
- package/src/adapters/conformance/local-pi.ts +100 -0
- package/src/adapters/conformance/owned-acp.ts +44 -0
- package/src/adapters/definitions/builtin-metadata.ts +25 -7
- package/src/adapters/definitions/native-cli-doctor.ts +12 -5
- package/src/adapters/definitions/native-cli-entry-jcode.ts +9 -6
- package/src/adapters/definitions/native-cli-entry-kimi.ts +7 -1
- package/src/adapters/definitions/native-cli-entry.ts +7 -19
- package/src/adapters/definitions/native-cli-jcode-mcp.ts +9 -2
- package/src/adapters/definitions/native-cli-preview-common.ts +2 -0
- package/src/adapters/definitions/native-cli-preview-jcode.ts +8 -2
- package/src/adapters/definitions/native-cli-preview-qwen.ts +2 -1
- package/src/adapters/definitions/native-cli-preview.ts +2 -11
- package/src/adapters/definitions/qwen-native.ts +7 -3
- package/src/adapters/definitions/qwen.ts +5 -1
- package/src/adapters/external-metadata.ts +48 -0
- package/src/adapters/external-module-scan.ts +126 -0
- package/src/adapters/external-modules.ts +240 -0
- package/src/adapters/jcode.ts +72 -31
- package/src/adapters/kimi-review.ts +6 -3
- package/src/adapters/pi.ts +2 -0
- package/src/adapters/public.ts +7 -0
- package/src/adapters/registry-types.ts +13 -1
- package/src/adapters/registry.ts +52 -15
- package/src/cli/agents.ts +40 -0
- package/src/cli/console-review.ts +54 -0
- package/src/cli/console-state.ts +124 -29
- package/src/cli/console-symbols.ts +74 -0
- package/src/cli/console-usage.ts +89 -0
- package/src/cli/console.ts +26 -1
- package/src/cli/help.ts +36 -21
- package/src/cli/identity.ts +30 -7
- package/src/cli/init.ts +109 -11
- package/src/cli/main.ts +145 -16
- package/src/cli/output.ts +44 -1
- package/src/cli/preview.ts +1 -1
- package/src/cli/sdlc-release-guard.ts +82 -0
- package/src/cli/upgrade-labels.ts +1 -1
- package/src/cli/upgrade-presentation.ts +1 -1
- package/src/cli/upgrade-restore-state.ts +3 -2
- package/src/cli/upgrade-runtime.ts +4 -1
- package/src/hub/action-class.ts +362 -0
- package/src/hub/action-policy.ts +106 -0
- package/src/hub/board.ts +72 -11
- package/src/hub/budget.ts +71 -2
- package/src/hub/bus.ts +43 -3
- package/src/hub/checks.ts +80 -31
- package/src/hub/code-facts.ts +223 -0
- package/src/hub/config-apply.ts +28 -11
- package/src/hub/config-reload.ts +8 -5
- package/src/hub/config-trust.ts +7 -4
- package/src/hub/control-client.ts +4 -1
- package/src/hub/daemon.ts +332 -61
- package/src/hub/dogfood-read.ts +199 -0
- package/src/hub/dogfood.ts +163 -0
- package/src/hub/envelope.ts +1 -1
- package/src/hub/events.ts +11 -2
- package/src/hub/facts.ts +76 -13
- package/src/hub/hub-tools.ts +45 -7
- package/src/hub/inbox-polling.ts +25 -0
- package/src/hub/instance-config.ts +17 -5
- package/src/hub/instance-execution.ts +20 -8
- package/src/hub/instances.ts +75 -2
- package/src/hub/peers.ts +9 -0
- package/src/hub/plan-conformance.ts +83 -0
- package/src/hub/profiles.ts +7 -2
- package/src/hub/release-worktree.ts +56 -0
- package/src/hub/review-brief.ts +36 -0
- package/src/hub/review-findings.ts +104 -0
- package/src/hub/roster.ts +31 -5
- package/src/hub/sdlc-queue.ts +48 -11
- package/src/hub/sdlc-release-authorization.ts +173 -0
- package/src/hub/sdlc-release.ts +16 -1
- package/src/hub/sdlc.ts +71 -18
- package/src/hub/settings.ts +10 -3
- package/src/hub/snapshots.ts +101 -14
- package/src/hub/symbol-normalizer.ts +26 -0
- package/src/hub/task-code-symbols.ts +90 -0
- package/src/hub/task-sweep.ts +3 -2
- package/src/hub/tasks.ts +556 -88
- package/src/hub/test-integrity.ts +162 -0
- package/src/hub/ui.ts +2 -2
- package/src/hub/usage-rollup.ts +361 -0
- package/src/local/sandbox.ts +5 -3
- package/src/ui/index.html +560 -78
- package/src/ui/office-model.ts +3 -1
- package/src/ui/peer-palette.ts +44 -0
- package/templates/AGENTS.block.md +1 -1
- package/templates/profiles/dev.json +6 -1
- package/templates/profiles/general.json +6 -1
- package/templates/profiles/research.json +6 -1
- package/templates/profiles/writing.json +6 -1
- package/templates/release-guard.block.md +6 -0
package/docs/operations.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Operations guide
|
|
2
2
|
|
|
3
|
-
This guide describes ahub 0.
|
|
3
|
+
This guide describes ahub 0.13.0 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
|
## Agent-operated live verification
|
|
@@ -61,7 +61,7 @@ smoke ledger; the presence of this option proves no outstanding #273 live leg.
|
|
|
61
61
|
|
|
62
62
|
## Command output
|
|
63
63
|
|
|
64
|
-
`ahub status`, `board`, `budget`, `doctor`, `projects`, `queue list`, `turns` and `
|
|
64
|
+
`ahub status`, `board`, `budget`, `doctor`, `projects`, `queue list`, `turns`, `report` and `usage` print shared console tables and labelled details.
|
|
65
65
|
`status --all` uses the projects table. `queue show`, `models status` and `budget execution status` show labelled fields; add `--json` for the raw fetched document.
|
|
66
66
|
`report --by task` keeps the attribution and coverage sentences with section headings and aligned counters.
|
|
67
67
|
Use `--json` for scripts; it returns the fetched data without color, and `status --json` keeps its existing document.
|
|
@@ -141,6 +141,30 @@ its footer. The active tab is bracketed, as in `[2 Approvals]`, so it reads
|
|
|
141
141
|
without color. The Approvals tab counts pending requests and the Queue tab
|
|
142
142
|
counts `needs_review` deliveries, in the attention and failure tones.
|
|
143
143
|
|
|
144
|
+
Tab `7 Usage` (#683 U3, key `7`; Left and Right wrap as Settings does, so the `1`..`5` cycle is unchanged) lists each peer with the tokens of today (the UTC day),
|
|
145
|
+
the last seven UTC days and its lifetime, the current budget pause, its quota windows with their reset time, and its last reset. Every number names its
|
|
146
|
+
source (`native`: the provider's own total, `hub`: what the hub counted for a peer that reports none, `at least`: a partial sum); a counter nobody reported
|
|
147
|
+
is `unknown` and a period with no records is `no records`, never 0. Enter opens a peer: today, 7 days and lifetime with input, output, cache read, cache
|
|
148
|
+
write and the hub count each on its own, and the last three resets. The task selected in Tasks when you press `7` is shown below the table with its tokens
|
|
149
|
+
per peer (`#id [pii]` for a private task, never a title). The panel asks the hub's `usage` op only while it is open, and a refusal shows as
|
|
150
|
+
`usage unavailable`. The numbers come from the roll-up of `ahub usage`, so the console and the CLI agree. A request folds the event log first, within 250 ms;
|
|
151
|
+
when a very large log is not folded yet the answer carries `behind: true`, the panel says `still catching up` and `ahub usage` prints a warning on stderr, so a partial number is never shown as the whole.
|
|
152
|
+
|
|
153
|
+
Reviewing from the console (#711): on a task in review in Tasks (a selected row, or the open task detail), `r` asks which verdict first on the prompt line,
|
|
154
|
+
`review #372 "<title>": a approve c request changes Esc cancel` (the title is quoted and cut, a private task shows `[pii]`). `a` puts `review 372 approved ` on
|
|
155
|
+
the input line with a guide line above it (`Enter approves #372. You can type a note first. Esc cancels.`); `c` puts `review 372 changes_requested ` there and
|
|
156
|
+
asks for what to fix (`Say what to fix, then Enter. Esc cancels.`): Enter with no note is refused in the console with `say what to fix before requesting
|
|
157
|
+
changes`, and nothing reaches the hub. The footer says `r approve or request changes`, and `your review: r approve or request changes` when the reviewer is
|
|
158
|
+
`user`, also while the task detail is open. When the command finishes the console shows `#372 approved` or `#372 changes requested`, or the CLI's refusal verbatim
|
|
159
|
+
as a failure notice, in panels mode too. A task that left review while the choice was open says `#372 is no longer in review (<state>)` and nothing is
|
|
160
|
+
prefilled. The console runs `ahub review` as the person; the hub still decides who may review, and nothing about authority changed.
|
|
161
|
+
|
|
162
|
+
An agent shell (a `!` command inside a Claude or Codex session, or any shell with `AGENTHUB_PEER_ID`, `CLAUDECODE` or `CODEX_THREAD_ID` set) runs as that agent, not as
|
|
163
|
+
you. When the hub refuses it something only the person or the task's own reviewer may do, stderr adds one line: `This shell runs as agent "claude" (AGENTHUB_PEER_ID
|
|
164
|
+
and CLAUDECODE are set), not as you. Run the command in your own terminal, or use the ahub console: Tasks, select #372, r.` The refusal and the authority are the
|
|
165
|
+
same as before, and the console identity never gets the line. The hub's notice that a task waits for your review now names the console path as well as
|
|
166
|
+
`ahub review N approved|changes_requested [note]`.
|
|
167
|
+
|
|
144
168
|
The console attention companion (#280) shows waiting, blocked, review, working,
|
|
145
169
|
idle or asleep with separate action/watch counts. Outside the Tasks table, `n` selects the exact approval,
|
|
146
170
|
held queue or review row, or prints applicable guidance; it never answers a
|
|
@@ -175,10 +199,10 @@ the stream; only the header is tab-flattened before tokenizing. Body lines retai
|
|
|
175
199
|
the previous rendering and stay plain, as does command output; colour never changes
|
|
176
200
|
what the panel's text says.
|
|
177
201
|
|
|
178
|
-
Peers, Approvals, Tasks, Queue and
|
|
202
|
+
Peers, Approvals, Tasks, Queue, Settings and Usage are tables with a header row. A column is as
|
|
179
203
|
wide as its widest cell, up to a third of the terminal; the last column takes
|
|
180
204
|
the rest and is cut with `...`. In Tasks, TITLE takes the rest and the STAGE
|
|
181
|
-
meter keeps a fixed column at the right edge.
|
|
205
|
+
meter keeps a fixed column at the right edge. In Usage, LAST RESET is the column that gives way on a narrow terminal.
|
|
182
206
|
|
|
183
207
|
| Panel | Columns |
|
|
184
208
|
|---|---|
|
|
@@ -188,6 +212,7 @@ meter keeps a fixed column at the right edge.
|
|
|
188
212
|
| Tasks, backlog view (`b`) | ID PRI RESERVED DEPS CLASS AGE TITLE |
|
|
189
213
|
| Queue | ID PEER STATE REV AGE |
|
|
190
214
|
| Settings | GROUP KEY VALUE SOURCE APPLIES |
|
|
215
|
+
| Usage | PEER TODAY 7D LIFETIME PAUSE QUOTA LAST RESET |
|
|
191
216
|
|
|
192
217
|
In Tasks, `b` toggles open work and backlog. The backlog heading counts its rows;
|
|
193
218
|
rows sort by rank, then id. PRI shows priority/rank, RESERVED the reserved peer,
|
|
@@ -320,7 +345,21 @@ owner and to stop working.
|
|
|
320
345
|
`ahub task assign <id> <peer> [--role owner|reviewer] [--revision N]` uses a
|
|
321
346
|
checked console operation when a revision is present. Without it, existing CLI
|
|
322
347
|
behavior is unchanged. `ahub queue resolve ... [--revision N]` uses the supplied
|
|
323
|
-
revision instead of a fresh show.
|
|
348
|
+
revision instead of a fresh show. A `queued` delivery was never handed to its peer, so it can be discarded while the peer is busy (a pull-only TUI is busy most of
|
|
349
|
+
the time); `dispatching` and `accepted` deliveries stay refused, and `retry` keeps its rules. A refused resolution names its cause (`active delivery`, `peer busy`,
|
|
350
|
+
`stale revision`, `unknown delivery`, `already resolved`, `queued delivery is already scheduled`, `recipient queue is full`, `delivery journal unavailable`), never one
|
|
351
|
+
generic sentence (#713).
|
|
352
|
+
|
|
353
|
+
`ahub queue discard --peer <id> --reason <text> [--state queued|needs_review] [--yes] [--json]` clears one peer's backlog and is for the person only (an agent identity is
|
|
354
|
+
refused). Without `--yes` it only says how many deliveries it would discard; with `--yes` it discards each queued (default) or `needs_review` delivery of that peer through the
|
|
355
|
+
same resolution as `queue resolve --action discard`, each recorded with the reason, and prints `discarded N of M` with the causes of any it could not discard. Only the
|
|
356
|
+
named peer's queue is read, so other peers are untouched; it is refused while recovery or shutdown holds queue mutations. In the console Queue panel, `D` on a row opens
|
|
357
|
+
the same command for that row's peer, asks for a reason, then a `y` that names the count. No task is cancelled and no native turn is stopped.
|
|
358
|
+
|
|
359
|
+
Completed-change notices (`Task #N (owner X) is done and touches your open ...`, #713) go one per recipient per done, naming all of that recipient's overlapping tasks, and
|
|
360
|
+
only for tasks the recipient has accepted (in progress, in review or changes requested): an offered or proposed task gets none, since its offer or its accept already shows the
|
|
361
|
+
current board. A newer notice for the same done task replaces the queued, undelivered one for that recipient (a `superseded completed-change notice` discard in the journal), so
|
|
362
|
+
a task that is sent back and done again three times leaves one queued notice, the newest. Revision mismatches and superseded post-await
|
|
324
363
|
publications fail without a board or delivery side effect; a reviewer-only change
|
|
325
364
|
keeps a valid owner assignment but refreshes its reviewer content.
|
|
326
365
|
|
|
@@ -635,6 +674,79 @@ Private envelopes and PII tasks stay redacted. Local-worker and Pi tool details
|
|
|
635
674
|
allow decisions stay in `ahub tail` / `ahub permit`; the page can deny them.
|
|
636
675
|
No dashboard port is opened until requested. See [the session security model](security.md#local-dashboard-sessions-issue-6).
|
|
637
676
|
|
|
677
|
+
### Dashboard design tokens (#469 R1)
|
|
678
|
+
|
|
679
|
+
The page's style block starts with one token block that owns every colour, the 4px spacing scale (4, 8, 12, 16, 24, 32), the
|
|
680
|
+
type scale (12, 13, 14, 16, 20) and the radius rule: 6px for controls, 10px for surfaces (panels, cards, the dialog), full
|
|
681
|
+
radius for chips and avatars. Neutrals are one cool family with three surface levels (page, panel, raised) and one accent for
|
|
682
|
+
primary actions, focus and selection; the state colours keep their meaning. The dark values are written twice, once for
|
|
683
|
+
`data-theme="dark"` and once for the system preference, and a test keeps the two identical. Two shadows exist for raised
|
|
684
|
+
elements only (`--shadow-2` is the dialog's; `--shadow-1` waits for the board cards in R3). Each peer colour has a light and a
|
|
685
|
+
dark variant of one hue, generated from the registry's colour by `peerPaletteThemeCss` (`src/ui/peer-palette.ts`) so it clears
|
|
686
|
+
3:1 on every surface. System fonts only. The layout, the views, the keys and the behaviour are unchanged by R1; the contrast
|
|
687
|
+
test (`test/office-view.test.ts`) covers the text pairs, the accent, the dots, disabled controls and every peer colour in both
|
|
688
|
+
themes. The Office scene keeps its own rules until R5.
|
|
689
|
+
|
|
690
|
+
### Dashboard app shell and keys (#469 R2)
|
|
691
|
+
|
|
692
|
+
From 1024px up, a sticky top bar holds the project context, the connection status (a coloured dot and its text, green when live
|
|
693
|
+
and red when disconnected or closed), the attention badge, the theme switch and a shortcuts button; the seven views sit in a
|
|
694
|
+
left sidebar with an icon and a label, and the approval count still rides on Agents. Below 1024px the same nav is one row of
|
|
695
|
+
tabs that scrolls sideways inside itself, so the page never scrolls sideways. The view names, their order, the
|
|
696
|
+
`agent-hub-view` cookie and every id are unchanged.
|
|
697
|
+
|
|
698
|
+
Keys: `1` to `7` switch to Board, Office, Stream, Agents, Message, Memory and Settings, `?` opens the key list, and `Esc` closes
|
|
699
|
+
the key list or the task detail (both are native dialogs). View keys are ignored while you type in an input, a textarea or a
|
|
700
|
+
select, with Ctrl, Alt or Cmd held, and while a dialog is open. Icons come from one inline SVG sprite of nine Tabler icons;
|
|
701
|
+
the MIT notice is in `THIRD_PARTY_NOTICES.md`. Nothing is fetched and no package is added.
|
|
702
|
+
|
|
703
|
+
### Dashboard board, side sheets and the Plan sheet (#469 R3)
|
|
704
|
+
|
|
705
|
+
A board card shows the title (two lines at most), the owner as a round avatar in the peer colour with its initial, one badge that
|
|
706
|
+
holds the state and the priority ("in review P1") and the release when there is one. Everything else moved to the task detail,
|
|
707
|
+
which keeps the same dialog and opens as a sheet pinned to the right edge (full screen below 600px). The detail groups its
|
|
708
|
+
lines into Status, People, Dates and Links, and leaves out a group with nothing in it. Pull, Assign, the Ready and Waiting
|
|
709
|
+
subheads, "Show N older" and drag and drop are unchanged.
|
|
710
|
+
|
|
711
|
+
The five board forms (plan a task, split a backlog task, releases, delivery evidence, propose a task) are in a Plan sheet, opened by
|
|
712
|
+
the Plan button in the board toolbar. It is a native dialog, so `Esc` closes it, and view keys do nothing while it is open. The
|
|
713
|
+
fields, ids and actions are the ones the forms had. The sheets slide in on `transform` and `opacity` and not at all when the
|
|
714
|
+
system asks for reduced motion.
|
|
715
|
+
|
|
716
|
+
### Dashboard Agents, Stream, Memory, Settings, Message and the Office colours (#469 R4, R5)
|
|
717
|
+
|
|
718
|
+
Agents: a peer is one row with its name and state, a summary line (queued messages and "Working on #n" or "No active task") and a
|
|
719
|
+
single "Details" fold that holds the diagnostic lines it used to list. A status notice stays visible outside the fold. Approvals
|
|
720
|
+
stay first. Stream: one aligned row per event (time, kind, sender, body in monospace); the filter chips and Follow latest sit in
|
|
721
|
+
the section head, above the scrolling list. Memory: result rows show title, kind and age, the selected row is marked with an accent
|
|
722
|
+
edge, and the graph and the detail pane use the colour tokens. Settings: each group is a section with a short header, a key that waits
|
|
723
|
+
for a restart carries a "restart pending" badge, and "Pending restart" shows a count; the text lines, Preview, Save and Undo are as
|
|
724
|
+
they were. Message uses the shared form styles.
|
|
725
|
+
|
|
726
|
+
Icons replace the symbol glyphs: the star mark, the stream arrow and the Office "checking" mark are sprite icons (twelve Tabler icons
|
|
727
|
+
in all), and the Office draws each condition (idle, busy, offline, paused, waiting on approval) as a shape (ring, disc, cross, bars, raised hand)
|
|
728
|
+
next to its words. Condition names are unchanged. The Office scene names its colours only through the same tokens as the rest of the page, and the
|
|
729
|
+
contrast test checks every token an Office rule uses, in both themes.
|
|
730
|
+
|
|
731
|
+
### Dashboard keyed rendering, motion and states (#469 R6)
|
|
732
|
+
|
|
733
|
+
The page still polls `/snapshot` once a second and still skips a redraw when a container's JSON did not change. What changed is how
|
|
734
|
+
a changed container is redrawn: task cards, peer rows and memory rows are kept per id. A card, row or memory entry whose own data
|
|
735
|
+
did not change keeps its DOM node, so hover, an open "Details" fold and a focused card survive a poll that changed something
|
|
736
|
+
else. One that changed is replaced by a fresh node, and if it held focus the focus moves to the replacement. A card that moves to
|
|
737
|
+
another column fades in; one that disappears is simply removed.
|
|
738
|
+
|
|
739
|
+
Motion moves `transform` and `opacity` only, 120 to 200 ms, ease-out: button press, a short fade when you switch views, a card
|
|
740
|
+
arriving in a column, the toast, and the side sheets. The Office keeps its own motion. Nothing new loops. With the system setting
|
|
741
|
+
"reduce motion" every transition and animation in the page is off.
|
|
742
|
+
|
|
743
|
+
States: until the first snapshot arrives, after a project switch too, the board and the peer list show grey blocks shaped like them. Each empty view says what
|
|
744
|
+
fills it and the command that does it (`ahub task propose`, `ahub claude` or `ahub codex`, `ahub say`, `ahub permit`, `ahub
|
|
745
|
+
remember`, `ahub goal new`). When a poll fails the connection status turns red, the content dims to 60 percent but stays readable,
|
|
746
|
+
and a line at the top gives the time of the last snapshot and says polling continues. Notices are a stack of up to four toasts in
|
|
747
|
+
the bottom corner (`aria-live="polite"`): a success fades after 4 seconds (and stays under reduce motion), an error stays until
|
|
748
|
+
you press Dismiss.
|
|
749
|
+
|
|
638
750
|
## Multiple projects and worktrees
|
|
639
751
|
|
|
640
752
|
Version 0.4.0 adds one independent hub per repository or Git worktree.
|
|
@@ -894,6 +1006,57 @@ conductor sees it, and only a stub for a PII task. Other peers are refused. Each
|
|
|
894
1006
|
request also carries the hub's review brief for the task's commit: reviewable and
|
|
895
1007
|
excluded files with reasons, the `REVIEW.md` and `ahub-review-rules` rules read at
|
|
896
1008
|
the merge base, and a cross-check list; `ahub review brief <id>` prints it.
|
|
1009
|
+
Optional code facts (#682) add per-file observed symbol names, kinds and spans,
|
|
1010
|
+
plus changed/planned, changed/not-planned and planned/not-seen lists. Install
|
|
1011
|
+
ripwire 0.6.7 on the daemon's host PATH to enable them; missing, unsupported,
|
|
1012
|
+
failed, busy or timed-out reads show `unknown` and never stop the review request.
|
|
1013
|
+
Each native call is capped at 5 s, output is capped, and successful values are
|
|
1014
|
+
cached by repo, commit and query. PII tasks never query it; displayed names use
|
|
1015
|
+
the hub's public metadata screen. It always analyzes a disposable raw-blob
|
|
1016
|
+
snapshot, never main or a dirty/untracked owner tree, and removes that worktree
|
|
1017
|
+
after the owned process stops. No heavy slot is acquired. Trees beyond the
|
|
1018
|
+
regular-file/4096-file/32-MiB bounds remain unknown.
|
|
1019
|
+
|
|
1020
|
+
Ripwire 0.6.7 omits deleted definitions and does not classify change kinds, so
|
|
1021
|
+
all symbol rows say `change: unknown`; planned/not-seen is not proof of no
|
|
1022
|
+
change. Graph name-only matches are hidden as ambiguous, and graph count floors
|
|
1023
|
+
remain explicit. The file-based coverage gate is unchanged. A future both-tree
|
|
1024
|
+
inventory or bounded base/head probes can improve this advice after dogfooding.
|
|
1025
|
+
|
|
1026
|
+
At completion, optional symbol advice also becomes a head-bound task observation
|
|
1027
|
+
(`#684` phase 2a). Console task detail and the UI task snapshot expose the
|
|
1028
|
+
screened IDs, paths, names and kinds, without source/spans or internal repository
|
|
1029
|
+
keys. Public reads re-screen current policy; PII stores nothing. Unknown or
|
|
1030
|
+
stale evidence remains unavailable. Completion prepares this optional data even
|
|
1031
|
+
without a reviewer, without adding a review gate. Foreign-repository tasks stay
|
|
1032
|
+
unknown until the brief can independently bind its analysis repository.
|
|
1033
|
+
|
|
1034
|
+
In the console, Enter on a task in Tasks shows a `symbols` block after its plan (#684 phase 2b): each observed changed symbol is `matching` the plan or
|
|
1035
|
+
`unplanned`, and each planned symbol that nothing changed under is `untouched`, with the counts and the head they were observed at. The match rule is the review
|
|
1036
|
+
brief's own (a pair of qualified names must be equal, otherwise the last segments are). Without code facts it reads `changed symbols: unknown (no code facts)`;
|
|
1037
|
+
an incomplete observation says an untouched symbol may have changed; a private task shows nothing. Names are quoted like every agent-written string, at most 40 are
|
|
1038
|
+
listed and the rest are counted. The block is advice: deleted definitions are not reported, so it never proves a plan was or was not followed.
|
|
1039
|
+
|
|
1040
|
+
Task detail also shows an `overlaps` block (#379), using the hub's read-only
|
|
1041
|
+
`symbolOverlaps` projection of its existing open-task/other-owner overlap selection.
|
|
1042
|
+
Each row names the other task ID and screened shared paths. A row says "same file,
|
|
1043
|
+
different symbols" only when the same current screened predicate used by completion
|
|
1044
|
+
notices establishes observed disjointness; otherwise it remains an ordinary overlap.
|
|
1045
|
+
The block states "observed names only, deleted definitions may be missing". PII tasks
|
|
1046
|
+
are excluded on both sides by their markers, even if the routing locality limit is
|
|
1047
|
+
disabled. No pair result is stored, and the console never infers
|
|
1048
|
+
one from its own plan or receipt. Missing fields on older hubs show no block; an
|
|
1049
|
+
empty list says `none`. At most 40 pairs and 40 paths per pair are listed, with
|
|
1050
|
+
omitted counts. Related-note counts remain a later slice.
|
|
1051
|
+
|
|
1052
|
+
When both tasks have complete public observations and non-empty disjoint sets
|
|
1053
|
+
for every exact shared file, a completed-change notice says "same file, different
|
|
1054
|
+
symbols" with the observed-name/deleted-definition ceiling. It still tells the
|
|
1055
|
+
recipient to check the completed work. Missing or partial evidence keeps the
|
|
1056
|
+
ordinary notice; plan-time overlap and coverage gates are unchanged. The receipt
|
|
1057
|
+
keeps one current head, with at most 500 entries and 64 KiB total. This is the
|
|
1058
|
+
data slice; the formatted Code panel and memory links follow separately.
|
|
1059
|
+
|
|
897
1060
|
`hub_review` takes `coverage {reviewed, skipped}`: in enforce an approval that leaves
|
|
898
1061
|
a reviewable path unaccounted is refused, and advise notes the gap in the verdict
|
|
899
1062
|
(#520). The hub
|
|
@@ -1027,8 +1190,14 @@ ahub report --since 7d # turns, busy time and tokens per peer, messages
|
|
|
1027
1190
|
ahub report --since 7d --json # the same numbers as JSON
|
|
1028
1191
|
ahub report --by task # tokens, turns and wall time per task and class, with the unattributed share
|
|
1029
1192
|
ahub export --since 24h # the raw events as JSON lines, for your own analysis
|
|
1193
|
+
ahub report --dogfood [--since 7d|<iso>] [--json] # read-only scorecard: flow, quality, cost, delivery, performance, adoption
|
|
1030
1194
|
```
|
|
1031
1195
|
|
|
1196
|
+
`ahub report --dogfood` (#687) reads the event log, `hub.log`, the board and the delivery journal in `hub.db`, up to 16 recently merged
|
|
1197
|
+
PRs through `gh`, and the feature table in `docs/dogfood.md`. It covers the last seven days by default, takes no `--by`, and prints the same
|
|
1198
|
+
document as `--json` with `unknown` in place of null; missing or truncated evidence is unknown, never 0. It exports ids, timestamps and counts
|
|
1199
|
+
only and runs no model. Its bounds and the weekly routine are in [dogfood](dogfood.md#weekly-scorecard).
|
|
1200
|
+
|
|
1032
1201
|
Per peer and model route, `ahub report` also counts model changes between consecutive
|
|
1033
1202
|
decisions, how many of them landed inside tool loops and, with `stay_switch` on, sessions
|
|
1034
1203
|
and the planner's switches (#197). With `stay_switch = "off"` session boundaries are not
|
|
@@ -1036,6 +1205,41 @@ recorded; `shadow` routes exactly as `off` does, so it is the baseline to compar
|
|
|
1036
1205
|
A route event records the decision, so a load-moved request that its MLX fallback served counts
|
|
1037
1206
|
as a change to `dgx/fast`; the relay's request journal records which backend served it.
|
|
1038
1207
|
|
|
1208
|
+
The event log also keeps the history of limits (#683). Each Codex update that adds tokens writes a
|
|
1209
|
+
`usage` event with source `codex_appserver` next to the existing `tokens` event, split into input, cached
|
|
1210
|
+
input, output and reasoning, so re-sent cached context is visible. A budget pause writes `budget_pause`
|
|
1211
|
+
and its end `budget_resume`, with the window, the reset time and who ended it (`hub`, or `person` for an
|
|
1212
|
+
`ahub budget resume`). A window's reset writes `quota_reset` when its `resetsAt` moves forward or its `used`
|
|
1213
|
+
falls by 0.5 or more inside one window id, once per peer, window and `resetsAt`. These events hold ids and
|
|
1214
|
+
numbers only, add no protocol version and are ignored by a reader that does not know them. `ahub report`
|
|
1215
|
+
does not show them: `ahub usage` and `ahub usage limits` read them (below), and the console's Usage tab shows each peer's last resets (#683 U3). A dashboard usage view is pending (U4).
|
|
1216
|
+
|
|
1217
|
+
`ahub usage` reads the same events from an incremental roll-up in `hub.db` instead of rescanning the log (#683):
|
|
1218
|
+
|
|
1219
|
+
```bash
|
|
1220
|
+
ahub usage [--since 7d|<iso>] [--by peer|task|issue|pr|release|day|model] [--json]
|
|
1221
|
+
ahub usage limits [--peer <id>] [--limit <n>] [--json] # current quota windows, plus the newest 200 (up to 5000) pauses, resumes and resets
|
|
1222
|
+
ahub usage total [--json] # lifetime development tokens since the first event, per peer and overall
|
|
1223
|
+
```
|
|
1224
|
+
|
|
1225
|
+
The daemon folds `events.jsonl` into `usage_rollup`, `token_rollup` and `limit_events` from a stored byte offset, at most 8 MiB per pass and
|
|
1226
|
+
only whole lines, and each pass commits its rows and the new offset together, so a crash repeats a pass and never half-applies one. A rebuild
|
|
1227
|
+
from byte 0 gives the same rows (tested). A log that was replaced by a shorter one is folded again from the start. On this project's 47 MB,
|
|
1228
|
+
238k-line log the first fold took about 170 ms and a `usage` command about 95 ms, against about 150 ms for `ahub report --by task`, which
|
|
1229
|
+
rescans the whole file on each call.
|
|
1230
|
+
`issue`, `pr` and `release` are the board's current links of each task, read when you ask, so a task linked later is counted under its issue
|
|
1231
|
+
for the history it already spent. A task with no link, and a record with no task, are `unattributed`.
|
|
1232
|
+
|
|
1233
|
+
Every number names its source: `native` (the provider's own counter), `hub count` (the hub's own `tokens` increments, which cover peers that
|
|
1234
|
+
report no usage record, such as Jcode and Kimi), or `unknown`. Unknown is never shown as 0. `TOTAL` includes cache reads and `WITHOUT CACHE`
|
|
1235
|
+
removes them; Claude's total is the sum of its four reported counters because its transcript carries none (`ahub report` still shows it as unknown), and a source whose input already
|
|
1236
|
+
contains the cached part (Codex, the gateway) gets no derived total. A lifetime total that mixes a native and a hub-counted peer is labelled
|
|
1237
|
+
`hub count`. When a peer is unknown the overall figure is `partial, at least`: a lower bound that leaves the named peers out, never a sum that counts them
|
|
1238
|
+
as 0 (it is `unknown` when no peer is known). The overall `WITHOUT CACHE` is unknown unless every peer's cache split is known.
|
|
1239
|
+
`usage limits` shows the newest 200 events and says `N older events are not shown` when it cuts (`--limit <n>`, up to 5000, shows more). A pause that the events
|
|
1240
|
+
never ended and the hub no longer holds (cleared by `ahub reset`, which keeps the log as it was) shows as `pause ended, end unknown`, not as open. A private task shows its id and `[pii]`, never
|
|
1241
|
+
a title. The person and a configured planner may read usage, in the console, the dashboard control link or the CLI; every other agent is refused.
|
|
1242
|
+
|
|
1039
1243
|
`ahub report` counts the same overlap warnings as `scripts/overlaps.ts`, from the
|
|
1040
1244
|
structured events instead of log lines. `--by task` uses the task each usage and
|
|
1041
1245
|
token record was attributed to when it was written: the delivery that started the
|
|
@@ -1301,7 +1505,10 @@ stays the default until an evaluation says otherwise (`docs/cooperbench.md`).
|
|
|
1301
1505
|
file that falls out of the 64 a peer touched is named until the peer reads
|
|
1302
1506
|
that back. Only regular files
|
|
1303
1507
|
of 256 KB or less inside the project are read, re-resolved at every read and
|
|
1304
|
-
opened without following links; larger ones are named without a diff
|
|
1508
|
+
opened without following links; larger ones are named without a diff, compared
|
|
1509
|
+
by size and modification time, or by their bytes while written in the last 2 s
|
|
1510
|
+
(4 MiB or less each, 16 MiB per store per event-loop turn), since a same-size
|
|
1511
|
+
rewrite within one filesystem timestamp tick keeps the stat. Facts never go through the bus or the delivery journal;
|
|
1305
1512
|
`events.jsonl` records `fact`, `fact_ack` and `capability` events with bytes
|
|
1306
1513
|
and latencies.
|
|
1307
1514
|
- Integration. A member's `hub_task_done` is a completion intent. The member
|
|
@@ -1375,6 +1582,14 @@ stays the default until an evaluation says otherwise (`docs/cooperbench.md`).
|
|
|
1375
1582
|
turns the stale-notice drop off, for a controlled comparison only (the #106
|
|
1376
1583
|
ablation in `docs/cooperbench.md`); the hub logs it at start.
|
|
1377
1584
|
|
|
1585
|
+
## Always-ask action policy foundation (#636)
|
|
1586
|
+
|
|
1587
|
+
The classifier, local configuration and session budget counter are available in source. Adapter enforcement is pending: each peer's `ahub status` row says `always-ask not enforceable: adapter integration pending`. A default-on policy does not add a pre-tool check to a native CLI by itself.
|
|
1588
|
+
|
|
1589
|
+
Only ignored, untracked `.agenthub/config.local.json` can hold `action_policy`. Its optional keys are `enabled` (default true), `always_ask` (a distinct subset of publish, external-write, destroy, install; default all), and `budgets` (per-class integers 0..1000; defaults 1, 5, 3, 2 respectively). Shared `config.json` cannot set this policy and gets no confirmation offer. A tracked or unknown-trust local file is ignored. Use `ahub settings set action_policy.enabled <true|false>` or `ahub settings set action_policy.budgets.<class> <n>` for registered settings; change `always_ask` in the local file and use the existing confirmed terminal reload. Policy publication invalidates cached grants and pending approval challenges. Startup currently reads the untracked local policy without a retained confirmation; this ceiling must be addressed before the adapter gates ship (#312/#313).
|
|
1590
|
+
|
|
1591
|
+
The ledger asks first and after the approved class budget is spent. Adapter integrations must request that class allowance explicitly; an ordinary one-time answer does not seed the cache, and a cached budget never suppresses a prompt required by the native mode. One approval includes its own invocation; budget zero asks for every invocation. A fresh native session resets counters, and status polls do not bind sessions. Unknown command syntax retains native permission handling. This foundation never changes a sandbox or bypasses a denied permission; per-adapter enforcement tests land with their integrations.
|
|
1592
|
+
|
|
1378
1593
|
## Permission modes for running peers
|
|
1379
1594
|
|
|
1380
1595
|
Use a plain terminal to inspect or change a running peer:
|
|
@@ -1714,7 +1929,11 @@ entries and fields. It contains machine paths and the peer identity, not a token
|
|
|
1714
1929
|
with a warning. `--print-command` shows the change and command without writing.
|
|
1715
1930
|
The configured `kimi_cmd` must be a single executable or end in exactly `acp`;
|
|
1716
1931
|
the TUI uses the executable or drops that final word. Other wrappers are refused
|
|
1717
|
-
with the headless command rather than guessed.
|
|
1932
|
+
with the headless command rather than guessed. The launcher uses the running
|
|
1933
|
+
hub's `kimi_cmd`; when that value has no TUI form, the refusal says so, since an
|
|
1934
|
+
edited file value waits for `ahub settings reload`.
|
|
1935
|
+
|
|
1936
|
+
After three empty inbox reads within ten minutes by a pull-only peer with no assigned task or review, the hub adds polling advice and one console notice per streak (peer id and counts only); a delivery or assignment resets it, and restart clears the in-memory counters.
|
|
1718
1937
|
|
|
1719
1938
|
The TUI is pull-only. Its model reads `hub_inbox` at the start of work, between
|
|
1720
1939
|
steps of longer work and before reporting, and shares results, and mid-work
|
|
@@ -1725,7 +1944,9 @@ and important markers do not push or interrupt it. There is no hub busy state,
|
|
|
1725
1944
|
watchdog, console approval, hub permission mode, context reading, automatic quota
|
|
1726
1945
|
pause/handoff, shared final answer or session resume. When important messages are
|
|
1727
1946
|
waiting, every other hub tool result ends with a line saying how many, so the model
|
|
1728
|
-
reads `hub_inbox` before starting long local work (#398).
|
|
1947
|
+
reads `hub_inbox` before starting long local work (#398). One `hub_inbox` read drains the queue oldest first up to
|
|
1948
|
+
64 KiB of rendered text and, when more waits, ends with `N more waiting: call hub_inbox again before you start work` (#713).
|
|
1949
|
+
Read quota and approve tools
|
|
1729
1950
|
in Kimi's own TUI; a person can pause the hub queue by hand. End the native terminal
|
|
1730
1951
|
session there, not with `ahub stop kimi`.
|
|
1731
1952
|
|
|
@@ -1895,8 +2116,9 @@ but cannot show pushes, so it attaches tools-only (protocol 16, issue #205):
|
|
|
1895
2116
|
`messages wait for hub_inbox; for pushes restart Claude with ahub claude`; the
|
|
1896
2117
|
console footer shows `tools-only: ahub claude` and the dashboard shows the
|
|
1897
2118
|
status line.
|
|
1898
|
-
- The session reads them with `hub_inbox`,
|
|
1899
|
-
the hub's recall note when one waits (
|
|
2119
|
+
- The session reads them with `hub_inbox`, which drains the queue oldest first (important messages marked, as ever) up to 64 KiB of rendered text plus
|
|
2120
|
+
the hub's recall note when one waits (#713; a push peer's digest is still ten items). When more is waiting the result ends
|
|
2121
|
+
`N more waiting: call hub_inbox again before you start work`. Each read is one `completed` delivery (`read through
|
|
1900
2122
|
hub_inbox` in `ahub queue list`); nothing is ever `accepted`, and the session
|
|
1901
2123
|
has no `hub_delivery_done`. A read the model never saw (the tool call was
|
|
1902
2124
|
cancelled, the plugin died) cannot be retried: `ahub queue show <id>` of the
|
|
@@ -1934,7 +2156,7 @@ bridge currently receives no positive per-server activation signal.
|
|
|
1934
2156
|
|
|
1935
2157
|
A Claude session started with `ahub claude` receives pushes when it is idle. While it is busy:
|
|
1936
2158
|
|
|
1937
|
-
- Every hub tool result carries fresh counts, `(N queued hub message(s), M important hub message(s) waiting: call hub_inbox before starting long local work)`, when important work waits. A zero count clears an earlier hint.
|
|
2159
|
+
- Every hub tool result carries fresh counts, `(N queued hub message(s), M important hub message(s) waiting: call hub_inbox before starting long local work)`, when important work waits. A zero count clears an earlier hint. Under a delivery hold that refuses pulls, the counts and held rows stay but the `hub_inbox` advice is dropped.
|
|
1938
2160
|
- `hub_inbox` reads the daemon queue (and any local failed-push buffer) in a channel session too. A read is one `completed` delivery, like a tools-only read; holds refuse it the same way.
|
|
1939
2161
|
- An important message is pushed into the running turn (steered) instead of waiting for the turn to end. Mid-turn reading was verified on Claude Code 2.1.302; an older client that drops it leaves the delivery `accepted` until a person resolves it. Ordinary messages still wait for the idle push or `hub_inbox`.
|
|
1940
2162
|
- Do not use `[FYI]` for PR ready, done, submitted, ruling-needed, blocker or changed-contract messages: they need action. `hub_task_done` and `hub_review` already notify their recipients.
|
|
@@ -2106,6 +2328,22 @@ killed.
|
|
|
2106
2328
|
Rows without a live process are stale registrations; forget them with
|
|
2107
2329
|
`ahub projects remove <id>`.
|
|
2108
2330
|
|
|
2331
|
+
## Agent CLI versions
|
|
2332
|
+
|
|
2333
|
+
Agent CLIs update themselves often, and a hub release cannot follow every one. One policy decides each gated CLI: the Codex and Kimi fresh reviewers, Jcode, agy and Qwen (#691).
|
|
2334
|
+
|
|
2335
|
+
- `ahub agents [--json]` lists each gated CLI with its version, verdict and verified versions.
|
|
2336
|
+
- **verified:** a receipt exists.
|
|
2337
|
+
- **in-line:** untested, inside the compatible line that a contract gate (Jcode, agy) declares; it starts with a note.
|
|
2338
|
+
- **trusted:** you accepted this exact version on this machine.
|
|
2339
|
+
- **refused:** the reason names the installed and verified versions and the command that admits it.
|
|
2340
|
+
- **unknown:** the CLI is not on PATH, or its version could not be read.
|
|
2341
|
+
- `ahub agents trust <id> <version>` accepts one untested version on this machine (`~/.agenthub/agent-compat.json`); `--revoke` undoes it. Only the person can run it; agent shells are refused.
|
|
2342
|
+
- For the reviewers, trust lifts only the version pin. The MCP inventory, Apps/plugins/hooks readback, sandbox denial fixtures and binary fence still run before every child, and a failed leg still refuses.
|
|
2343
|
+
- What trust cannot prove is printed when you trust.
|
|
2344
|
+
- `ahub doctor` shows one line for each installed CLI that is not on a verified version.
|
|
2345
|
+
- A weekly workflow (`.github/workflows/agent-compat.yml`) compares the latest npm versions of Codex, Kimi Code and Qwen Code with the verified sets, keeps one `agent-compat` issue up to date while one is ahead and closes it when none is. The next step for each listed version is a model-free receipt in `docs/verification/`, then adding it to `verified` in the same PR. Jcode and agy are not watched.
|
|
2346
|
+
|
|
2109
2347
|
## Upgrade and crash recovery
|
|
2110
2348
|
|
|
2111
2349
|
On a terminal, one command reviews, applies and follows an upgrade:
|
|
@@ -3271,7 +3509,7 @@ that the file is untracked; a dropped value is reported by the settings result.
|
|
|
3271
3509
|
|
|
3272
3510
|
## SDLC artifact receipts and gates
|
|
3273
3511
|
|
|
3274
|
-
The playbook lifecycle (#257, #481) is off without `.agenthub/sdlc.toml`. When enabled its stages are intent, spec, plan, build, test, review, merge, release and maintain, grouped as Plan, Design, Build, Test, Deploy and Maintain. Advise shows blockers; enforce checks implemented head-bound review and approval gates. Stored implement/verify receipts read as build/test; new enabled receipts use canonical ids. See [the SDLC contract](sdlc.md) for gates, required check names, local receipts, console-only readbacks and the S0-S8 delivery table. A person accepts a spec issue with `ahub sdlc accept <task> --issue <n>` (S1). The planner records plan reviews with review and CI scope (`hub_plan_review`, `ahub sdlc plan-review`) and grooms with `ahub backlog groom`; `ahub backlog return <task> <revision> <reason>` returns accepted, untouched work (S9). `ahub sdlc costs [owner/repo]` reports review rounds and CI runs of merged PRs without writing the board (S10). S11 release trains ship in 0.12.37 (see [release scheduling](#planner-release-scheduling)). S2-S7 and a full live advise/release cycle remain pending. Owners/reviewers record bounded identities through `hub_sdlc_record`; these grant no additional authority. Off output, receipt and schema shapes stay unchanged.
|
|
3512
|
+
The playbook lifecycle (#257, #481) is off without `.agenthub/sdlc.toml`. When enabled its stages are intent, spec, plan, build, test, review, merge, release and maintain, grouped as Plan, Design, Build, Test, Deploy and Maintain. Advise shows blockers; enforce checks implemented head-bound review and approval gates. Stored implement/verify receipts read as build/test; new enabled receipts use canonical ids. See [the SDLC contract](sdlc.md) for gates, required check names, local receipts, console-only readbacks and the S0-S8 delivery table. A person accepts a spec issue with `ahub sdlc accept <task> --issue <n>` (S1). The planner records plan reviews with review and CI scope (`hub_plan_review`, `ahub sdlc plan-review`) and grooms with `ahub backlog groom`; `ahub backlog return <task> <revision> <reason>` returns accepted, untouched work (S9). `ahub sdlc costs [owner/repo]` reports review rounds and CI runs of merged PRs without writing the board (S10). S11 release trains ship in 0.12.37 (see [release scheduling](#planner-release-scheduling)). S3 structured review findings (an open Important finding blocks approval in enforce; `max_nits` in `sdlc.toml` caps nits) and S2 literal-path plan conformance with the person-only `ahub sdlc accept-departure <task> <head> <reason...>` are in source; see [findings](sdlc.md#structured-review-findings-481-s3) and [plan conformance](sdlc.md#plan-conformance-481-s2). S4-S7 and a full live advise/release cycle remain pending. Owners/reviewers record bounded identities through `hub_sdlc_record`; these grant no additional authority. Off output, receipt and schema shapes stay unchanged.
|
|
3275
3513
|
## Optional Qwen Code peer
|
|
3276
3514
|
|
|
3277
3515
|
Select Qwen per project with `ahub roster add qwen`; it defaults off and is absent
|
|
@@ -3280,11 +3518,12 @@ starts its ACP peer. `--print-command` previews; TUI is refused until #286's
|
|
|
3280
3518
|
verification. `ahub stop qwen` stops the owned process group. A conductor may start
|
|
3281
3519
|
it only through the selected roster and existing capabilities.
|
|
3282
3520
|
|
|
3283
|
-
|
|
3521
|
+
Receipt-verified native ACP identities are qwen-code 0.25.0 and 0.26.0 ([dated receipt](verification/2026-10-22-kimi-qwen-compat.md)). A CLI version label alone
|
|
3284
3522
|
is insufficient: startup verifies its native identity/version and advertised mode
|
|
3285
|
-
ids before any prompt. The
|
|
3286
|
-
its package/ACP source
|
|
3287
|
-
|
|
3523
|
+
ids before any prompt. The earlier local installation reported CLI 0.25.0 while
|
|
3524
|
+
its package/ACP source said 0.24.1; that was not a ready identity. The 0.26.0 receipt
|
|
3525
|
+
used a private prefix and did not upgrade PATH. Configure `qwen_cmd` only in
|
|
3526
|
+
untracked config.local.json with a receipt-verified executable.
|
|
3288
3527
|
The provider's tunnel/relay, if needed, must already be available. Startup cannot
|
|
3289
3528
|
prove network readiness from a version command.
|
|
3290
3529
|
|
|
@@ -3316,11 +3555,11 @@ TUI input may interleave with an ACP turn; there is no single-writer guard. Clos
|
|
|
3316
3555
|
After upgrading to the recipient-retry release, a Jcode project MCP entry written before `AGENTHUB_DELIVERY_ONLY` was added is intentionally stale. Once per project, the person runs `ahub jcode --mode headless` before using conductor/dashboard starts. The launcher rewrites only the owned entry with the delivery-only marker, preserving foreign entries and refusing collisions; recovery relaunches already use this CLI path. Readiness checks never rewrite the file, and an explicit false marker or any other drift remains refused. Until that rewrite, daemon starts keep their actionable stale-entry refusal rather than advertising a retry tool Jcode cannot use.
|
|
3317
3556
|
|
|
3318
3557
|
|
|
3319
|
-
Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or runtime mode mapping is invented. Quota and consumption remain unknown. Supported versions run from 0.98.0 up to, not including, 1.0.0 (#529). Every owned jcode process (version probe, daemon, ACP and TUI) runs with `JCODE_NO_TELEMETRY=1`. Native session/load (verified on 0.94.0 and 0.98.1) cannot prove 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.
|
|
3558
|
+
Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or runtime mode mapping is invented. Quota and consumption remain unknown. Supported versions run from 0.98.0 up to, not including, 1.0.0 (#529); another version is refused before the owned daemon starts, with the version named and the trust command (#691). Every owned jcode process (version probe, daemon, ACP and TUI) runs with `JCODE_NO_TELEMETRY=1`. Native session/load (verified on 0.94.0 and 0.98.1) cannot prove 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.
|
|
3320
3559
|
|
|
3321
3560
|
## Optional Antigravity (agy) peer
|
|
3322
3561
|
|
|
3323
|
-
Antigravity is optional and off roster by default. Use `ahub roster add agy`, then run `ahub agy` in a terminal: it runs the Antigravity CLI as a fresh pull-only TUI in that terminal. It accepts the 1.4.x line: 1.4.2 is the verified version, any other 1.4.x launches with a stderr warning (agy updates itself), and other versions are refused (#589). The running hub must advertise `native_hook_launch`; an older hub refuses before any write with an upgrade-or-restart remedy. Only the person's launcher starts it: conductor starts are refused, there is no controlled restore or resume, and a declared agy extra instance is refused when the config loads (#625). Headless/print, resume (`--conversation`, `--continue`, `--new`), `--mode`, `--dangerously-skip-permissions` and `--unattended` are refused until their native mapping is verified; `--print-command` previews without writing.
|
|
3562
|
+
Antigravity is optional and off roster by default. Use `ahub roster add agy`, then run `ahub agy` in a terminal: it runs the Antigravity CLI as a fresh pull-only TUI in that terminal. It accepts the 1.4.x line: 1.4.2 is the verified version, any other 1.4.x launches with a stderr warning (agy updates itself), and other versions are refused (#589) unless the person trusts that exact version with `ahub agents trust agy <version>` (#691). The running hub must advertise `native_hook_launch`; an older hub refuses before any write with an upgrade-or-restart remedy. Only the person's launcher starts it: conductor starts are refused, there is no controlled restore or resume, and a declared agy extra instance is refused when the config loads (#625). Headless/print, resume (`--conversation`, `--continue`, `--new`), `--mode`, `--dangerously-skip-permissions` and `--unattended` are refused until their native mapping is verified; `--print-command` previews without writing.
|
|
3324
3563
|
|
|
3325
3564
|
The launcher writes exactly `plugin.json`, `mcp_config.json` and `hooks.json` in `.agents/plugins/agent-hub/`, refusing linked or foreign entries before any write, and removes only its own matching files when the TUI ends. It never writes project-level `.agents/hooks.json` or the person's `~/.gemini` settings. Run `ahub init` afterwards to ignore the untracked plugin directory; a tracked plugin is written with a warning. The native model sees the hub tools under the server name `agent-hub_agent-hub`.
|
|
3326
3565
|
|
|
@@ -3366,11 +3605,15 @@ Extra instances use the existing `instances` block. For example, `"myagent-revie
|
|
|
3366
3605
|
|
|
3367
3606
|
Configured kinds are cloud peers and never receive PII work. Quota and context are unknown, and a kind with no budget source is exempt from quota accounting, so pause it by hand if its provider refuses. After a crash the hub resumes a recorded session through `session/load` only when the agent echoes the same id, and it never reuses a recorded model. Controlled recovery (`ahub upgrade`, `restart`, `recovery`) refuses a running configured kind: stop it, then start it again with its session id. While the project declares adapters, the upgrade or restart target must advertise `configured_acp`.
|
|
3368
3607
|
|
|
3608
|
+
## External adapter modules (#451 A4)
|
|
3609
|
+
|
|
3610
|
+
A bundled adapter module is authorized by the person with `adapter_modules` (at most 16 rows of `path` and `sha256`) in an untracked `.agenthub/config.local.json`; in `config.json` or a tracked file it is ignored with a notice, and settings never edit it. Only daemon startup imports a module: settings, reload, previews and CLI reads never do, so a change needs a restart. The module must be a single self-contained ESM file inside the project (no symlinked, world-writable or oversized file) whose bytes match the pin, and it may import only Node/Bun builtins and `@staix/agent-hub/adapter`; the scanner also refuses any `require`, `eval` or `Function` word token. Each import must settle within 2 s. A module that fails any check is refused on its own, with a bounded reason in the status reply, while startup and the other adapters continue; its roster row stays inert. A loaded kind is headless, cloud (never PII), off roster until `ahub roster add <kind>`, and has no controlled recovery: stop it and start it again with its recorded session id. While modules are declared, the upgrade or restart source and target must advertise `external_adapter_modules`. Bundling, the accepted definition subset and the conformance kit (`@staix/agent-hub/conformance`, for module CI only) are in [Adding an AI tool](adding-an-ai-tool.md#5-external-adapter-modules-451-a4). A pin authorizes code that runs with the daemon's rights; it is not a sandbox ([security](security.md)).
|
|
3611
|
+
|
|
3369
3612
|
# Headless ACP watch (#286)
|
|
3370
3613
|
|
|
3371
3614
|
- 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`.
|
|
3372
3615
|
- 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.
|
|
3373
|
-
- 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
|
|
3616
|
+
- 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 a receipt-verified ACP identity. `ahub qwen --mode tui` remains refused.
|
|
3374
3617
|
- Protocol stays 16; a same-protocol older daemon answers the new request as unknown, which the CLI reports. Since 0.12.44 a headless start that the hub itself makes for Kimi or Qwen opens this view automatically through the terminal provider (see Start modes; #286).
|
|
3375
3618
|
- Native T0 limits: [ACP watch verification](verification/2026-10-11-acp-watch-t0.md).
|
|
3376
3619
|
|
|
@@ -3801,8 +4044,62 @@ restart the hub. For example, a reviewer can use:
|
|
|
3801
4044
|
|
|
3802
4045
|
Start them with `ahub codex --as codex-review` and
|
|
3803
4046
|
`ahub kimi --as kimi-review`. Codex keeps its native TUI and its own hub-owned
|
|
3804
|
-
app-server proxy; extra Kimi, Qwen, Pi and local instances use headless starts.
|
|
3805
|
-
Extra Jcode instances are
|
|
4047
|
+
app-server proxy; extra Kimi, Qwen, Jcode, Pi and local instances use headless starts.
|
|
4048
|
+
Extra Jcode instances are supported (#685), in `.agenthub/config.local.json` only:
|
|
4049
|
+
|
|
4050
|
+
```json
|
|
4051
|
+
{
|
|
4052
|
+
"instances": {
|
|
4053
|
+
"jcode-claude": { "kind": "jcode", "roles": ["verifier"], "jcode_home": "/Users/you/.agenthub/jcode/claude",
|
|
4054
|
+
"provider": "claude", "model": "claude-sonnet-5-5" },
|
|
4055
|
+
"jcode-local": { "kind": "jcode", "roles": ["verifier"], "jcode_home": "/Users/you/.agenthub/jcode/local",
|
|
4056
|
+
"provider_profile": "onprem" }
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
4059
|
+
```
|
|
4060
|
+
|
|
4061
|
+
`jcode_home` is required, absolute, and must differ from the base `jcode_home`, from
|
|
4062
|
+
every other instance's and from any directory inside or around them, however it is
|
|
4063
|
+
spelled: a symlink, a system alias such as `/tmp` and `/private/tmp`, or a case-only
|
|
4064
|
+
alias is the same home (the hub refuses the configuration at startup otherwise). At most 8 Jcode instances are accepted per
|
|
4065
|
+
project. `provider`, `model` and `provider_profile` are optional and passed to Jcode
|
|
4066
|
+
as `-p`, `--model` and `--provider-profile` exactly as written; any other field is
|
|
4067
|
+
refused, and these fields are never editable from settings.
|
|
4068
|
+
|
|
4069
|
+
You authenticate inside Jcode, never in the hub. Run Jcode's own setup against each
|
|
4070
|
+
home (provider login, API key, an OpenAI-compatible base URL such as the on-prem
|
|
4071
|
+
gateway, a provider profile), and initialize that home's MCP store with Jcode's own
|
|
4072
|
+
client, as for the base peer. The hub never reads, writes, copies or injects a model
|
|
4073
|
+
credential, a key, a token or a provider URL, and never creates the home. Its only
|
|
4074
|
+
start preflight is read-only: the home must exist as a directory you own, otherwise
|
|
4075
|
+
the start is refused and nothing runs. A Jcode sign-in failure appears as the start
|
|
4076
|
+
or turn error, with bounded text. An instance reports tokens only if Jcode itself
|
|
4077
|
+
does; until then they show `unknown`, never 0.
|
|
4078
|
+
|
|
4079
|
+
Each instance owns its private `jcode serve` and `jcode acp` pair, socket, roster row
|
|
4080
|
+
and launch record, and acts as its own peer id (for example `jcode-local`), never as
|
|
4081
|
+
`jcode`. Start it with `ahub jcode --as jcode-local` (headless; an instance has no
|
|
4082
|
+
TUI) and stop it with `ahub stop jcode-local`: the base Jcode and every other instance
|
|
4083
|
+
keep running. An extra implementer needs the same managed worktree as every extra
|
|
4084
|
+
implementer (`worktree: ".worktrees/jcode-local"`). Every instance is a cloud peer
|
|
4085
|
+
(`trust.onPrem` is false), whatever provider you configured: it never receives PII
|
|
4086
|
+
work. `ahub status` and the dashboard show the provider, model and profile as
|
|
4087
|
+
declared, and `ahub doctor` lists the MCP servers each rostered instance's home would
|
|
4088
|
+
load.
|
|
4089
|
+
|
|
4090
|
+
Upgrade note (#368): the project's `.jcode/mcp.json` entry for Jcode no longer names
|
|
4091
|
+
`AGENTHUB_PEER_ID`, because the file is shared by every Jcode in the project and Jcode
|
|
4092
|
+
gives an entry's own env precedence over the process env. Each hub-started Jcode now
|
|
4093
|
+
supplies its own peer id and a launch id, and the hub admits a hub-tools connection
|
|
4094
|
+
for Jcode only with the launch id of that peer's current owned launch. After
|
|
4095
|
+
upgrading, `ahub status` and `ahub doctor` report the Jcode MCP entry as not ready
|
|
4096
|
+
once (`jcodeMcpReady` is false for the old entry): run `ahub jcode` once and it
|
|
4097
|
+
rewrites its own entry, or follow the remedy text the start refusal shows. A Jcode you
|
|
4098
|
+
run yourself in this project outside the hub has no peer id: its hub tools refuse
|
|
4099
|
+
every call with that reason and never default to `jcode`, and a process that only
|
|
4100
|
+
sets `AGENTHUB_PEER_ID` without an owned launch is refused by the hub.
|
|
4101
|
+
|
|
4102
|
+
An extra Claude instance is a reviewer or
|
|
3806
4103
|
planner you start yourself: declare it with `roles` only (for example
|
|
3807
4104
|
`"claude-review": { "kind": "claude", "roles": ["reviewer"] }`, no `start_mode` or
|
|
3808
4105
|
`worktree`) and run `ahub claude --as claude-review` in a terminal. It keeps its own
|
|
@@ -3819,7 +4116,9 @@ the builder's summary or agent chat, and the board records its verdicts as
|
|
|
3819
4116
|
the planner reviews and the task's assignment note says `reviewer=planner (fallback)`.
|
|
3820
4117
|
A missing
|
|
3821
4118
|
`peer_instances` feature on an old daemon or upgrade target requires a supporting
|
|
3822
|
-
version before launching or restoring extras.
|
|
4119
|
+
version before launching or restoring extras. An older recovery source without it
|
|
4120
|
+
is refused only while a declared instance is live or unreadable; a source whose
|
|
4121
|
+
status shows every declared id offline proceeds.
|
|
3823
4122
|
|
|
3824
4123
|
### Fresh reviewer pool (#519)
|
|
3825
4124
|
|
|
@@ -3838,9 +4137,9 @@ From 0.12.37 reviews can rotate across fresh headless Claude and Codex reviewers
|
|
|
3838
4137
|
|
|
3839
4138
|
Start them with `ahub claude --as claude-review`, `ahub codex --as codex-review` and `ahub kimi --as kimi-review`; stop with `ahub stop <id>`. Fresh Claude and Codex variants share the project checkout; the Kimi variant runs in a clean temporary working directory and reviews only the screened brief and host facts. All fresh variants refuse a custom worktree or permission mode. Codex and Kimi require `review_mode: "fresh"`; without it, an existing headless instance with the reviewer role keeps its native app-server/ACP behavior, worktree and permission options and does not join this pool. Claude retains its #223 automatic headless-reviewer declaration. The agy reviewer slot remains automatically unavailable (`agy is an implementer peer (#485)`). A failed or unsupported fresh start never downgrades to a native continuing session. Ordinary implementer instances retain their own adapters. The default logical pool order is Claude, Codex, Kimi. Only configured kinds with at least one declared reviewer count as slots, including declared ones that are offline, paused, quota-limited or failing, so availability never renumbers them; configured kinds with no declaration are listed after the walk as `no declared reviewer`. `review.rerotate` defaults to false. Pool selection starts at PR number modulo the number of declared kind slots, or task id when there is no PR, then skips the implementer's family and unavailable candidates. Delta review prefers the preceding eligible independent family in a fresh child. A preceding same-family fallback does not outrank a newly available independent family. `ahub route explain` shows the same pure walk.
|
|
3840
4139
|
|
|
3841
|
-
Codex requires
|
|
4140
|
+
Codex requires a verified `codex-cli` (0.146.0 or 0.163.0) or one the person trusts on this machine, and a passing bounded runtime receipt before its model child starts. Both verified versions passed the [2026-10-22 model-free production admission](verification/2026-10-22-codex-reviewer-isolation.md). A refusal names the installed and verified versions. Either set `codex_bin` to a verified executable, or run `ahub agents trust codex-review <version>`: trust lifts only the version pin, and every proof below still runs before each child (#691). The producer checks native binary/config stability, configured MCP inventory with only the two hub tools, effective Apps/plugins/hooks disablement, an explicit empty legacy `notify` command and a named filesystem profile. Apps needs separate feature readback because configured inventory omits runtime connectors. Web search is requested disabled; its effective turn mode is not read back and managed requirements can select Cached (see the verification ceiling). Each launch proves public-read, exact/glob/symlink private-denial, standard host credential denial and write-denial in temporary fixtures. Standard credential and configured tool-home/XDG subtrees are denied independently of project `local.deny`. Its sandboxed shell is filesystem read-only with private paths denied and network configured disabled; it is not Claude's Read/Grep/Glob-only tool whitelist. No credential home is copied.
|
|
3842
4141
|
|
|
3843
|
-
Kimi requires Kimi Code
|
|
4142
|
+
Kimi requires a compat-admitted Kimi Code on the hub's PATH (receipt-verified 2.2.0 and 2.3.0), signed in through its managed OAuth provider, and a passing runtime preparation before each child; an unverified/untrusted version or a failed preparation is unavailable with its reason. The [2.3.0 receipt](verification/2026-10-22-kimi-qwen-compat.md) is model-free and does not verify real login/provider readiness. Each review runs a new `kimi -p` child without Seatbelt, in a private `KIMI_CODE_HOME` with managed-provider-only config, a clean temporary working directory and an empty skills directory. Its agent may call only `hub_review` and `hub_task_show`, through a task-bound loopback MCP session that never carries the hub's control token, and has no native read, file or shell tool: it reviews the screened brief and host facts only. Its `credentials/`, `oauth/` and `device_id` link to the person's native Kimi files, so it shares the native login, refresh lock and the Kimi account's budget; no token is copied. A stop revokes its verdict authority first, then waits briefly while an OAuth refresh holds the lock; a forced stop mid-refresh may require a native re-login. The Kimi backend records no measured token counts here, so its usage stays unknown; the 2.3.0 receipt makes no usage claim. This is a native tool-authority boundary, not filesystem or network isolation.
|
|
3844
4143
|
|
|
3845
4144
|
A dangling or unreadable standard/configured credential root makes the Codex reviewer unavailable with only its path class in the reason (for example `~/.docker` or `$DOCKER_CONFIG`, never an expanded path or contents); repair the root and start the reviewer again.
|
|
3846
4145
|
|
|
@@ -3854,11 +4153,19 @@ An additional implementer must have an existing registered Git worktree and
|
|
|
3854
4153
|
attached branch at `.worktrees/<instance-id>`, named explicitly by `worktree` in
|
|
3855
4154
|
its declaration. The hub validates it and does not create it in this phase.
|
|
3856
4155
|
Reviewer instances may share the checkout, or name their own validated worktree.
|
|
3857
|
-
The execution directory is separate from the canonical hub project.
|
|
4156
|
+
The execution directory is separate from the canonical hub project. Resolving it
|
|
4157
|
+
(at an extra-instance start and for a turn undo) makes up to four git calls that
|
|
4158
|
+
share one 5 s allowance; when it runs out the start refuses with `Git workspace
|
|
4159
|
+
evidence unavailable`. An Orca
|
|
3858
4160
|
terminal may belong to either that canonical project or the instance's execution
|
|
3859
4161
|
worktree; recovery preserves its exact recorded grouping and live launcher.
|
|
3860
4162
|
Changing or removing the declaration invalidates its saved extra-instance
|
|
3861
|
-
binding
|
|
4163
|
+
binding; the recovery screen and `--verbose` receipt still show what was recorded
|
|
4164
|
+
for it. A roster key left by an undeclared instance (`codex-2`) loads as inert and
|
|
4165
|
+
`ahub roster remove codex-2` deletes it from `.agenthub/config.local.json`; a key
|
|
4166
|
+
held only in the shared `config.json` is refused with a request to edit that file.
|
|
4167
|
+
Any other unknown roster key is still an unsupported peer. Do not infer ownership
|
|
4168
|
+
from a native-kind label alone.
|
|
3862
4169
|
|
|
3863
4170
|
A routing preference for a kind chooses among its instances using current load
|
|
3864
4171
|
and WIP. A manual instance id remains exact. Reviewers from the same kind share
|
|
@@ -3873,6 +4180,14 @@ CLI checks the saved workspace against the current declaration again before any
|
|
|
3873
4180
|
context change or file restoration. Removing the declaration intentionally
|
|
3874
4181
|
blocks that undo until the identity and workspace can be reviewed.
|
|
3875
4182
|
|
|
4183
|
+
## Release approval and optional tag guard
|
|
4184
|
+
|
|
4185
|
+
Run `ahub sdlc authorize-release <version>` from the running daemon's release-candidate checkout in a person's terminal after committed documentation is fresh. The receipt binds commit, package version, remote identity and the docs verdict. Agents and delegated live-test calls cannot authorize. The daemon keeps approval only in memory and logs metadata for audit; restart requires a new approval. The read-only `ahub sdlc release <owner/repo>` report shows its receipt, retaining native-verification blockers.
|
|
4186
|
+
|
|
4187
|
+
`ahub init --release-guard` installs a managed Git pre-push guard and release instructions (`--dry-run --json` previews them). It preserves an existing default hook as `pre-push.agent-hub-original` and passes original argv/stdin to it only after approval matches. Unknown or mismatched `v*` tag pushes fail closed, including when the daemon is down. Non-version branch pushes remain independent of the daemon. Custom `core.hooksPath` and linked/hardlinked hook files require manual integration. Re-run init after changing the Bun/package location. The person's `git push --no-verify` remains an explicit bypass; agents are instructed never to use it.
|
|
4188
|
+
|
|
4189
|
+
For `gh release create` and `npm publish`, use the exact literal command after `ahub sdlc release-guard --`. This preflight reads evidence and never executes the command. New GitHub tags require an explicit full commit target; alternate-repository, workspace/archive and bulk target forms refuse. GitHub/npm adapter enforcement is deferred to #312/#313. This consent record does not certify a tarball, native acceptance or live publication. Detailed limits: [S6 authorization](sdlc.md#person-release-authorization-481-s6).
|
|
4190
|
+
|
|
3876
4191
|
## Planner release scheduling
|
|
3877
4192
|
|
|
3878
4193
|
Use `ahub sdlc train report <release-id>` for scope readiness and recorded release metrics. The planner creates future release rows, activates one train, and assigns tasks through the release-only hub tools. A due date requests a cut review; it never clears unfinished work. Move missed tasks to the next row with a reason, then use `ahub sdlc train cut <release-id> <revision>` from the person's terminal or `hub_release_cut` as the planner. The cut retains a short host admission lease through freeze and defers on held gate slots or unknown/quota-limited peer windows with a real quota source. Accounts without a quota reader (Kimi included when `kimi_tokens_5h` is zero) report `no quota source`; manual and budget-record pauses still defer. It does not run release preparation or publish anything. Schedule bundle/check/docs work under separate heavy admission and retain the person's native verification, authorization and upgrade window. A hotfix records its enumerated cause and keeps every gate.
|
|
@@ -3886,3 +4201,11 @@ If Codex is offline with `statusNotice.code = unidentified-cancellation`, the hu
|
|
|
3886
4201
|
could not identify a cancelled native turn. Reattach the native session before
|
|
3887
4202
|
further hub delivery. A late completion keeps this hold; verified native
|
|
3888
4203
|
reattachment or TUI detachment clears it. The notice contains fixed guidance, without native ids.
|
|
4204
|
+
|
|
4205
|
+
## Roles per SDLC stage (#525, planned)
|
|
4206
|
+
|
|
4207
|
+
The design for planner, implementer and reviewer instances per stage is in the spec section "Amendment: roles per SDLC stage (#525)". Nothing in it is available yet. Each implementation slice (525-1 to 525-6) adds its operator steps here when it ships. Until then, the instance rules in "Additional headless peer instances" above are current. The planned changes an operator will see:
|
|
4208
|
+
|
|
4209
|
+
- A Claude instance with `["implementer"]` and a `worktree`, as a terminal instance (started with `ahub claude --as <id>`) or as `start_mode: "headless"` (`permission_mode` `ask` or `ask-when-needed`; `never-ask` refused).
|
|
4210
|
+
- The `planner` setting accepts a list of peers or instance ids; each task records its own planner, and only that planner or the person runs planner tools on it.
|
|
4211
|
+
- A reviewer is never a peer that implemented the task, and a plan's author does not record its own plan review while another planner is available.
|