@staix/agent-hub 0.15.0 → 0.17.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 +43 -0
- package/README.md +12 -8
- package/docs/agent-notes/README.md +4 -0
- package/docs/agent-notes/adapters.md +24 -8
- package/docs/agent-notes/budget.md +4 -2
- package/docs/agent-notes/daemon.md +11 -4
- package/docs/agent-notes/local-worker.md +2 -2
- package/docs/agent-notes/tasks.md +15 -3
- package/docs/agent-notes/tests.md +8 -3
- package/docs/dogfood.md +18 -6
- package/docs/events.md +1 -1
- package/docs/memory.md +78 -10
- package/docs/operations.md +160 -47
- package/docs/quickstart.md +13 -5
- package/docs/roles.md +1 -0
- package/docs/sdlc.md +11 -11
- package/docs/security.md +94 -22
- package/docs/smoke.md +58 -6
- package/docs/specs/2026-09-19-agent-hub-design.md +124 -12
- package/docs/specs/2026-09-20-upgrade-recovery-design.md +3 -1
- package/docs/verification/2026-10-24-always-ask-adapters.md +52 -0
- package/docs/verification/2026-10-24-amem-runtime.md +69 -0
- package/docs/verification/2026-10-24-codex-0164-reviewer-isolation.md +55 -0
- package/docs/verification/2026-10-24-delivery-holds-ac8.md +264 -0
- package/docs/verification/2026-10-24-hardcoded-values.md +2108 -0
- package/docs/verification/2026-10-25-0.16.0.md +82 -0
- package/docs/verification/2026-10-25-0.17.0.md +74 -0
- package/docs/verification/2026-10-25-codex-0164-reviewer-tool-call.md +52 -0
- package/docs/verification/2026-10-25-kimi-231-reviewer-compat.md +48 -0
- package/docs/verification/2026-10-25-kimi-usage-ac11.md +48 -0
- package/docs/verification/2026-10-25-qwen-dual-output-hub-e2e.md +23 -0
- package/docs/verification/2026-10-25-qwen-dual-output-t0.md +20 -0
- package/docs/verification/2026-10-25-reviewer-no-verdict-diagnostics.md +35 -0
- package/docs/verified.json +30 -18
- package/package.json +2 -2
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +3421 -2176
- package/src/adapters/acp.ts +5 -2
- package/src/adapters/codex-appserver.ts +69 -1
- package/src/adapters/codex-review-isolation.ts +10 -1
- package/src/adapters/compat.ts +9 -4
- package/src/adapters/conformance/enrollment.ts +18 -4
- package/src/adapters/conformance/factories.ts +4 -1
- package/src/adapters/conformance/kit.ts +11 -0
- package/src/adapters/definitions/builtin-metadata.ts +3 -3
- package/src/adapters/definitions/native-cli-entry-qwen.ts +32 -4
- package/src/adapters/definitions/native-cli-preview-qwen.ts +9 -1
- package/src/adapters/definitions/native-factories.ts +8 -0
- package/src/adapters/definitions/native-recovery.ts +8 -0
- package/src/adapters/definitions/qwen.ts +7 -4
- package/src/adapters/local-worker.ts +5 -4
- package/src/adapters/qwen-dual.ts +578 -0
- package/src/adapters/registry-types.ts +6 -2
- package/src/adapters/registry.ts +9 -1
- package/src/adapters/reviewer-mcp.ts +12 -6
- package/src/adapters/reviewer-print.ts +100 -17
- package/src/cli/console-state.ts +20 -2
- package/src/cli/console-symbols.ts +3 -2
- package/src/cli/console-usage.ts +5 -2
- package/src/cli/console.ts +5 -1
- package/src/cli/help.ts +7 -5
- package/src/cli/identity.ts +3 -1
- package/src/cli/main.ts +44 -10
- package/src/cli/memory.ts +119 -7
- package/src/cli/output.ts +12 -4
- package/src/cli/upgrade.ts +4 -3
- package/src/hub/action-class.ts +211 -17
- package/src/hub/action-enforce.ts +13 -5
- package/src/hub/action-policy.ts +19 -8
- package/src/hub/ask.ts +16 -4
- package/src/hub/board.ts +86 -31
- package/src/hub/budget-notes.ts +65 -0
- package/src/hub/budget.ts +42 -10
- package/src/hub/bus.ts +1 -1
- package/src/hub/code-facts.ts +56 -16
- package/src/hub/conductor.ts +5 -2
- package/src/hub/config-apply.ts +7 -0
- package/src/hub/control-client.ts +1 -1
- package/src/hub/daemon.ts +384 -71
- package/src/hub/envelope.ts +1 -1
- package/src/hub/events.ts +2 -2
- package/src/hub/hub-tools.ts +3 -3
- package/src/hub/kimi-usage.ts +12 -0
- package/src/hub/lifecycle.ts +10 -5
- package/src/hub/memory-code-head.ts +44 -0
- package/src/hub/memory-code-overlay.ts +119 -0
- package/src/hub/memory-plan-guard.ts +11 -27
- package/src/hub/memory-stale-anchors.ts +159 -0
- package/src/hub/memory-symbols.ts +74 -0
- package/src/hub/planning.ts +10 -4
- package/src/hub/read-tools.ts +21 -3
- package/src/hub/sdlc.ts +34 -0
- package/src/hub/settings.ts +17 -2
- package/src/hub/settled-roles.ts +15 -3
- package/src/hub/task-sweep.ts +25 -3
- package/src/hub/tasks.ts +378 -76
- package/src/hub/token-window.ts +15 -2
- package/src/hub/window-kind.ts +13 -0
- package/src/local/tools.ts +5 -5
- package/src/memory/brief.ts +66 -16
- package/src/memory/capture.ts +26 -40
- package/src/memory/client.ts +137 -65
- package/src/memory/recall.ts +13 -22
- package/src/ui/index.html +100 -18
package/docs/operations.md
CHANGED
|
@@ -5,6 +5,8 @@ results and remaining prerequisites are recorded separately in [the smoke ledger
|
|
|
5
5
|
|
|
6
6
|
## Agent-operated live verification
|
|
7
7
|
|
|
8
|
+
Every open live leg in [smoke.md](smoke.md#open-live-legs-by-class) is classed `agent-executable`, `agent-evidence / person-verdict`, `person-only` or `external-blocked` (#784); this section is how an agent runs the first two.
|
|
9
|
+
|
|
8
10
|
When the user explicitly authorizes a live test, its agent may run console
|
|
9
11
|
commands using `ahub --live-test [--project <path|id>] <command> [args...]`.
|
|
10
12
|
For example, `ahub --live-test --project <scratch-path> ui --no-open` starts the
|
|
@@ -794,9 +796,12 @@ initialization pair `AGENTHUB_PROJECT_DIR` / `AGENTHUB_STATE_DIR`.
|
|
|
794
796
|
|
|
795
797
|
Manager-started hubs use attended mode and project configuration, including
|
|
796
798
|
credential-file references. They do not inherit the launching project's gateway
|
|
797
|
-
URL/key overrides. Native memory
|
|
798
|
-
|
|
799
|
-
|
|
799
|
+
URL/key overrides. Native memory is shared by memory project key: the project's
|
|
800
|
+
normalized `origin` remote (without one, its git chain and main working root),
|
|
801
|
+
mapped through the person's `amem alias` log, so a worktree or subdirectory uses
|
|
802
|
+
its main checkout's key. The manager's shared-alias notice compares project-name
|
|
803
|
+
chains instead (superprojects down to the repository, `<parent>/<worktree>` for a
|
|
804
|
+
worktree). Neither means that task boards or agent sessions are shared. Provider quota readings
|
|
800
805
|
may describe the same account and should not be added across projects.
|
|
801
806
|
|
|
802
807
|
Before upgrading an older hub, inspect the plan with the matching CLI.
|
|
@@ -828,7 +833,8 @@ what the hub runs, which files it sends as credentials, where task text goes,
|
|
|
828
833
|
how far the local worker's sandbox reaches, or how often a peer asks before it
|
|
829
834
|
acts (`kimi_cmd`, `permission_modes`, `codex_bin`,
|
|
830
835
|
`pi.cmd`, `checks`, `mlx.bin`, `mlx.runtimeDir`, `mlx.modelPath`, `omniroute.urls`,
|
|
831
|
-
`omniroute.access_hosts`, the `omniroute` key files, `memory.worker_url
|
|
836
|
+
`omniroute.access_hosts`, the `omniroute` key files, `memory.worker_url` (still
|
|
837
|
+
accepted, ignored since 0.16.0),
|
|
832
838
|
`local.read_allow`, `local.bash_network`, `local.network_allow`) are machine-local:
|
|
833
839
|
they apply only from a file git confirms nobody committed. Put them in
|
|
834
840
|
`.agenthub/config.local.json` (`ahub init` adds it to `.gitignore`), which is
|
|
@@ -1285,7 +1291,7 @@ ahub task label 12 reverted # a later verdict (ok, regressed, reverted, i
|
|
|
1285
1291
|
|
|
1286
1292
|
## Hub memory
|
|
1287
1293
|
|
|
1288
|
-
The hub opens the selected memory profile under `memoryHome()` (default `~/.agenthub/memory/`)
|
|
1294
|
+
The hub opens the selected amem memory profile under `memoryHome()` (default `~/.agenthub/memory/`), with no claude-mem worker dependency ([how it works](memory.md)): notes saved
|
|
1289
1295
|
against an open task are short-term; when the task is approved its decisions, contracts and fails become long-term.
|
|
1290
1296
|
Task briefs, session-start recall and `ahub ask` read it first, and the dashboard has a Memory section.
|
|
1291
1297
|
|
|
@@ -1298,9 +1304,9 @@ ahub memory forget 1a2b3c4d # a person's; also promote, demote, sup
|
|
|
1298
1304
|
|
|
1299
1305
|
`"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
|
|
1300
1306
|
|
|
1301
|
-
The exact-pinned `@staix/agent-mem` 0.
|
|
1307
|
+
The exact-pinned `@staix/agent-mem` 0.7.0 resolves `AMEM_HOME`, then `$AGENTHUB_HOME/memory`, then `~/.agenthub/memory`. An absent `M/profile.json` selects shared v1; an explicit generation selects `M/generations/G` with the package's readonly legacy bridge. All daemon memory consumers and the hub memory/goal CLI use that selected profile. Invalid metadata or a missing selected generation makes native memory unavailable while the bus and board continue; there is no fallback to legacy writes. Inspect the daemon's memory binding/availability before interpreting missing memory as an empty store.
|
|
1302
1308
|
|
|
1303
|
-
The daemon checks its selector at hub operation entry and before candidate/counter writes. It does not hot-switch handles or provide an atomic fence against selection changes during an in-flight core call. Quiesce consumers and close their handles before migration or selection changes; reopen through the supported session-preserving lifecycle afterward. Candidate/counter storage remains `M/candidates.db`, independent of `G`; `amem review` on a generation
|
|
1309
|
+
The daemon checks its selector at hub operation entry and before candidate/counter writes. It does not hot-switch handles or provide an atomic fence against selection changes during an in-flight core call. Quiesce consumers and close their handles before migration or selection changes; reopen through the supported session-preserving lifecycle afterward. Candidate/counter storage remains `M/candidates.db`, independent of `G`; since agent-mem 0.7.0 `amem review` also lists and accepts candidates on a selected generation. Every running hub using this home needs an authenticated receipt: a matching ready binding, or a generation-capable unbound receipt (`disabled` when native memory is off, `unavailable` when opening failed) proving it holds no memory handle. An unbound daemon and zero running hubs are quiesced for memory; a stale bound handle, unreadable registry or unknown runtime is not ready. Existing JSON memory/goal results remain unchanged; the additive binding receipt belongs to daemon status, profile-check and the decay object. This source integration does not authorize installing a new runtime, migrating real memory, restarting sessions or claiming real-machine sync/capture receipts. Migration/deactivation and their limits belong to [agent-mem](https://github.com/STAIxBWLB/agent-mem); see [the hub profile contract](memory.md#selected-memory-profile).
|
|
1304
1310
|
|
|
1305
1311
|
Run `ahub memory profile-check [--json]` from the person's terminal for the read-only preflight. It identifies live registry owners by signed process identity and authenticated daemon replies, then reports their loaded memory package and bound home/profile. The receipt names the current `AGENTHUB_HOME` registry scope; zero results establish no live daemon in that inventory, not system-wide process absence. Inventory and check separate custom registries too when they share `AMEM_HOME`. A missing or unreadable runtime receipt never counts as a different home or permission to migrate.
|
|
1306
1312
|
|
|
@@ -1310,7 +1316,7 @@ A curated split (`amem migrate --shards`) writes `M/shards.json`; from 0.12.37 t
|
|
|
1310
1316
|
|
|
1311
1317
|
Managed agents read through `hub_memory_search`, `hub_memory_show` and `hub_memory_graph`, with the server's project identity, the `memory_read` capability and current privacy screening. They cannot supply another project; private turns are refused. The tools bound UTF-8 input/output, screen before counts and truncation, and exclude their arguments/results from hub-managed capture. `hub_memory_correct` has its own `memory_correct` capability and records a screened correction candidate, not a note change. See [the complete memory contract](memory.md) for caps and refusal semantics.
|
|
1312
1318
|
|
|
1313
|
-
Review candidates and rendered/delivered/cited counters stay in machine-local `M/candidates.db`, outside sync, import, recall, briefs, ask and graph evidence. Public changes-requested reviews with unmet items may propose a fail candidate; missing cause/retry details stay unknown.
|
|
1319
|
+
Review candidates and rendered/delivered/cited counters stay in machine-local `M/candidates.db`, outside sync, import, recall, briefs, ask and graph evidence. Public changes-requested reviews with unmet items may propose a fail candidate; missing cause/retry details stay unknown. Acceptance is a person's `amem review` action with its TTY/policy checks, on shared v1 and, since agent-mem 0.7.0, on a selected generation. Read-time `(stale?)` hints and plan-fail advice never change stored rows or task authority. Structured fail notes are validated against 4000 UTF-8 bytes before screening or writes, with no silent truncation.
|
|
1314
1320
|
|
|
1315
1321
|
Recall presentation omits generated task-approval outcome notes and shows only nonempty reasons from generated changes-requested notes; an ordinary decision that merely resembles a header stays visible. Contracts and fails remain eligible. Capped recall lines preserve memory headers and end at word boundaries, and one delivery deduplicates ids across restored/current prefaces and shared note lines. Stored notes and brief evidence are unchanged; platform recall retains its budget split.
|
|
1316
1322
|
|
|
@@ -1323,6 +1329,8 @@ ahub goal # open ones
|
|
|
1323
1329
|
ahub goal take 1a2b3c4d --force # take one over from another machine
|
|
1324
1330
|
```
|
|
1325
1331
|
|
|
1332
|
+
Without a remote the periodic sync stays quiet; any other sync failure writes `hub memory sync failed: <reason>` to `hub.log` (#401).
|
|
1333
|
+
|
|
1326
1334
|
## Benchmarks
|
|
1327
1335
|
|
|
1328
1336
|
In a git repository kept for benchmarks (`"bench": { "enabled": true }` in its `.agenthub/config.json`, a clean tree),
|
|
@@ -1606,20 +1614,24 @@ stays the default until an evaluation says otherwise (`docs/cooperbench.md`).
|
|
|
1606
1614
|
|
|
1607
1615
|
## Always-ask action policy foundation (#636)
|
|
1608
1616
|
|
|
1609
|
-
The classifier, local configuration and session budget counter decide
|
|
1617
|
+
The classifier, local configuration and session budget counter decide. The managed Claude PreToolUse hook (including the headless Claude implementer, #525-4), ACP permission requests with a host gate, received Codex command approval requests, and the hub-owned local/Pi tool boundary consume the same policy. Jcode still has no hub pre-tool approval path and remains listed as not enforceable. A default-on policy adds a pre-tool check only where the hub sees the call before it runs, and each peer's status row says whether it does.
|
|
1610
1618
|
|
|
1611
1619
|
What is enforced, and where it is not:
|
|
1612
1620
|
|
|
1613
1621
|
| Peer | Enforced | Not enforceable (the status row says why) |
|
|
1614
1622
|
| --- | --- | --- |
|
|
1615
1623
|
| Claude (`ahub claude`) | the managed PreToolUse hook returns `ask` for a classed call in `ask`, `ask-when-needed` and `never-ask` alike, and `ask` beats every allow the hook would add | a session with no hub permission hook, or one whose attached session has not yet run it (the launch record outlives the process, so it proves nothing alone: the status row says `no live Claude session has run the hub permission hook yet`); an `--unattended` launch (`--dangerously-skip-permissions` skips every permission check, hooks included); a hub that cannot answer the hook leaves Claude's own policy |
|
|
1616
|
-
| Kimi and other hub-owned ACP peers (headless) | `session/request_permission` for a classed call is never auto-approved (not even for a hub-owned tool title), carries `Action approval (<classes>): <command>`, withholds `allow_always`, and under `ahub --unattended` still waits for a person and expires as a denial | a peer in its native `ask-when-needed` (`yolo`) or `never-ask` (`auto`) mode: Kimi sends no request for a call that mode allows, so the hub cannot see it; the status row says `its native mode never-ask sends no request for a call it allows`. Switch the peer to `ask` to enforce. A request whose payload the agent did not report is not classed (unknown follows the mode) |
|
|
1624
|
+
| Kimi and other hub-owned ACP peers with a host approval gate (headless) | `session/request_permission` for a classed call is never auto-approved (not even for a hub-owned tool title), carries `Action approval (<classes>): <command>`, withholds `allow_always`, and under `ahub --unattended` still waits for a person and expires as a denial | a peer in its native `ask-when-needed` (`yolo`) or `never-ask` (`auto`) mode: Kimi sends no request for a call that mode allows, so the hub cannot see it; the status row says `its native mode never-ask sends no request for a call it allows`. Switch the peer to `ask` to enforce. A request whose payload the agent did not report is not classed (unknown follows the mode) |
|
|
1625
|
+
| Claude headless implementer | the managed hook asks for classed calls, and the current-child-bound prompt tool accepts only a person's allow-once or denial; ask and ask-when-needed retain their native requirements | an idle/offline implementer without a current child; never-ask and unattended are refused at startup |
|
|
1626
|
+
| Codex app-server | received command approval RPCs (v2 command execution or legacy exec) are classed before reaching the TUI; a classed request offers only allow-once/deny and an explicit bounded class-budget choice | status conservatively says not enforceable: native policy can execute without emitting an approval request; never-ask sends approvalPolicy never. writeStdin, absent/unknown payloads, file-change and permission-profile requests retain native handling |
|
|
1627
|
+
| Local worker and Pi | every model tool call is classed at the host permit boundary before never-ask, ask-when-needed or Pi's tool-wide grant; unattended never answers a classed request. Pi replayed call ids return the stored result without spending again | an offline local worker or Pi without a verified live bridge; Pi's verified person-authored idle shell remains the person's command, not a model tool call |
|
|
1628
|
+
| Jcode | no hub pre-tool approval path | always-ask not enforceable; its unmanaged native policy remains authoritative |
|
|
1617
1629
|
|
|
1618
|
-
Class budgets: the approval of a classed ACP call offers one extra choice, `Allow <class> xN for this session`, when the class budget is above one. Only that choice (never an ordinary allow) spends the ledger: it allows this call and the next N-1 of the same classes in the same native session, then asks again; several requests open at once share it, so a budget of N never lets more than N approved calls through. A new native session, a changed policy or a stopped, crashed or restarted peer starts from zero, even when it resumes the same session id. A budget of one is the single call the ordinary allow already covers. Claude's own permission dialog cannot carry that choice, so every classed Claude call asks.
|
|
1630
|
+
Class budgets: the approval of a classed ACP, received Codex command, local or Pi call offers one extra choice, `Allow <class> xN for this session`, when the class budget is above one. Only that choice (never an ordinary allow) spends the ledger: it allows this call and the next N-1 of the same classes in the same native session, then asks again; several requests open at once share it, so a budget of N never lets more than N approved calls through. A new native session, a changed policy or a stopped, crashed or restarted peer starts from zero, even when it resumes the same session id. A budget of one is the single call the ordinary allow already covers. Claude's own permission dialog cannot carry that choice, so every classed Claude call asks. Local/Pi show the complete tool title plus its class on the person's console, including private turns. Other surfaces retain the screened public view. Any view that remains cut (`[cut, N chars]`) or withheld offers denial only, with no allow-once or class-budget choice.
|
|
1619
1631
|
|
|
1620
|
-
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
|
|
1632
|
+
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 reads the untracked local policy without a retained confirmation. A policy that disables enforcement, omits a class or increases a class budget appends an attention notice to every status policy row. `ponytail:` this makes weakened startup policy visible, but the startup confirmation ceiling remains open; the upgrade is retained person-bound startup confirmation.
|
|
1621
1633
|
|
|
1622
|
-
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.
|
|
1634
|
+
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. A command with no classed literal prefix retains native permission handling; around a shell expansion the literal words are classed, and where the opaque part could change the class the strictest reachable class applies (#756, #762; [security](security.md)). This foundation never changes a sandbox or bypasses a denied permission; per-adapter enforcement tests land with their integrations.
|
|
1623
1635
|
|
|
1624
1636
|
## Permission modes for running peers
|
|
1625
1637
|
|
|
@@ -1839,7 +1851,7 @@ A guarded file edit that the daemon keeps at its accepted value remains visible
|
|
|
1839
1851
|
| Switches | `task_sweep.enabled`, `.auto_reassign`, `.interval_s`, `.unaccepted_min`, `.idle_min`, `.review_min`, `.ready_min`, `.ladder_min`, `.no_writes_turns` | `config.local.json` | live; `.no_writes_turns` sets the turn threshold independently; other keys reschedule the sweep timer |
|
|
1840
1852
|
| Routing | `tasks.wip_limits.<peer>` | `config.local.json` | live |
|
|
1841
1853
|
| Routing | `tasks.escalate_after` (1-10, default 3: consecutive `changes_requested` before a task moves to the next `escalate_to` peer) | `config.local.json` | live; the next verdict uses it |
|
|
1842
|
-
| Roles | `planner` (
|
|
1854
|
+
| Roles | `planner` (one or up to eight planner holders) | `config.local.json` | at once |
|
|
1843
1855
|
|
|
1844
1856
|
- Writes go only to `.agenthub/config.local.json` and `.agenthub/routing.local.toml`,
|
|
1845
1857
|
the machine-local files (`ahub init` ignores both in git). The shared
|
|
@@ -2101,6 +2113,24 @@ A budget pause remains authoritative until the budget command explicitly
|
|
|
2101
2113
|
overrides it or the window resets. Check `ahub status` and `ahub board` after
|
|
2102
2114
|
a pause or handoff.
|
|
2103
2115
|
|
|
2116
|
+
`ahub budget` (#285 phase 4) prints one row per window and a line for every attached peer that has no number. The KIND column says what the
|
|
2117
|
+
number is, and SOURCE where it came from; MEASURED is its age.
|
|
2118
|
+
|
|
2119
|
+
| Kind | Meaning | Source examples |
|
|
2120
|
+
| --- | --- | --- |
|
|
2121
|
+
| `native` | the provider's own ratio and reset | `claude status line`, `codex rateLimits`, `kimi ACP usage-limit refusal` |
|
|
2122
|
+
| `count` | tokens the hub counted, against a ceiling a person set | `hub count, kimi wire log, of kimi_tokens_5h 800000` (window `tokens`) |
|
|
2123
|
+
| `manual` | a person fed it with `ahub budget set <peer> <0..1> [--window 5h\|week] [--resets-in 2h]` | `ahub budget set` |
|
|
2124
|
+
|
|
2125
|
+
A count never claims to be the provider's quota. For one window and peer a manual value replaces the provider's at the gate, and while any native
|
|
2126
|
+
or manual reading is fresh the count is shown as `info only` and does not gate or feed routing headroom; when those go stale, or reset, the
|
|
2127
|
+
count gates again. A provider's hard refusal clears the person's number for that window, so a pause is never outvoted. A peer without a number says
|
|
2128
|
+
why instead: Pi and local print `no quota: on-prem ... has no provider quota` with the hub's own 5 h token count (information, never a meter);
|
|
2129
|
+
Kimi without `budget.kimi_tokens_5h` says it reports context occupancy only; an unreadable Kimi wire log says so with a reason code; a peer whose
|
|
2130
|
+
source has not reported yet says which. `--json` carries `kind`, `source`, `superseded` and a `peers` list of those notes; an older hub answers
|
|
2131
|
+
without them and the CLI classifies a window by its source. `ahub doctor` adds the row `kimi usage source` (counting, no ceiling, or unreadable).
|
|
2132
|
+
The console's peer detail (Enter on Peers) and the Usage detail, and the dashboard's Usage budgets row, show the same kind and source per window.
|
|
2133
|
+
|
|
2104
2134
|
Kimi Code CLI 2.1.1's observed 5-hour usage-limit refusal creates a hard budget reading (`kimi ACP usage-limit refusal`). `ahub status` shows a budget pause and `ahub budget` shows its source and reset estimate. The refusal gives no reset timestamp, so the hub estimates the reset at five hours after it was observed and resumes on the next budget tick after the existing one-minute grace. With `budget.wait_max_min` below that estimate, the existing budget relay automatically hands open tasks to an attached eligible peer; routing skips Kimi while paused. No checkpoint is requested from an exhausted agent.
|
|
2105
2135
|
`ahub budget resume kimi` overrides the reading so the provider can be tried early. A new provider refusal ends that override and pauses it again; a pending soft checkpoint cannot postpone this hard pause.
|
|
2106
2136
|
During one hub run, an early override followed by the same window's refusal keeps its earlier future reset bound; a provider's explicit reset remains authoritative. A restored pause without a per-window reading cannot identify that earlier window, so its next refusal starts a new estimate.
|
|
@@ -2259,14 +2289,16 @@ dashboard manager does the same when its home directory vanishes.
|
|
|
2259
2289
|
|
|
2260
2290
|
## The planner (#455)
|
|
2261
2291
|
|
|
2262
|
-
|
|
2263
|
-
backlog and sweep notices. `ahub status`
|
|
2264
|
-
|
|
2292
|
+
Planner holders propose and split tasks and read project-wide grooming. Each
|
|
2293
|
+
task's effective planner gets its backlog and sweep notices. `ahub status`
|
|
2294
|
+
prints the holders with their source, the dashboard's Agents view shows a
|
|
2295
|
+
Planner badge, and the console marks their rows.
|
|
2265
2296
|
|
|
2266
2297
|
- `setting`: `planner` in `.agenthub/config.json` or `config.local.json` (the
|
|
2267
|
-
machine's file wins)
|
|
2268
|
-
the role.
|
|
2269
|
-
|
|
2298
|
+
machine's file wins), either one id or a list of up to eight distinct ids.
|
|
2299
|
+
Only those peers hold the role. Builtins are `claude`, `codex`, `kimi`, `qwen`
|
|
2300
|
+
and `jcode`; a declared planner-capable instance is also eligible. A singleton
|
|
2301
|
+
settings write stores a string for older configuration readers.
|
|
2270
2302
|
- `roles`: with no `planner` key, the `roles` planners stand. That is `claude`
|
|
2271
2303
|
by default.
|
|
2272
2304
|
- `automatic`: when no rostered peer holds the role, the hub gives it to the
|
|
@@ -2275,9 +2307,39 @@ dashboard's Agents view shows a Planner badge, and the console marks its row.
|
|
|
2275
2307
|
|
|
2276
2308
|
Change it with `ahub settings set planner codex`, the dashboard Settings row
|
|
2277
2309
|
(a settings session, `ahub ui --settings`) or `l` in the console. Planning
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2310
|
+
holders and their backlog notices update at once. Use a comma list, for example
|
|
2311
|
+
`ahub settings set planner claude,codex`, to select several holders and follow
|
|
2312
|
+
any displayed holder-change confirmation. Role text updates at the next peer
|
|
2313
|
+
start. `ahub settings undo` restores the previous designation. Agents cannot
|
|
2314
|
+
change it.
|
|
2315
|
+
|
|
2316
|
+
New tasks record their planner through the same pure assignment walk shown by
|
|
2317
|
+
`ahub route explain`. Only that effective planner or the person changes their
|
|
2318
|
+
planning. A bound holder keeps authority while busy, offline or paused. If it
|
|
2319
|
+
is removed or leaves the roster, authority falls back to the current holders;
|
|
2320
|
+
the stored binding remains available for audit. Old tasks and releases with a
|
|
2321
|
+
null planner retain the legacy holder-wide authority. PII tasks keep null.
|
|
2322
|
+
The person names a different holder with
|
|
2323
|
+
`ahub task assign <id> <peer> --role planner`; this leaves the owner, reviewer,
|
|
2324
|
+
state and delivery offer intact. A planner-created release belongs to that
|
|
2325
|
+
planner; a person-created release keeps null.
|
|
2326
|
+
|
|
2327
|
+
A plan review is the exception: another settled holder may review a plan even
|
|
2328
|
+
when it is not that task's planner, without gaining its other planning powers.
|
|
2329
|
+
An agent author cannot self-review while another rostered non-offline planner
|
|
2330
|
+
exists. With no independent holder, the receipt says `selfReview: true`; it
|
|
2331
|
+
also records `planAuthor` (null when unknown). A person's own-plan override is
|
|
2332
|
+
marked self-review too. Independent requests contain ids only. Controlled
|
|
2333
|
+
recovery requires `task_planners` once a list/instance planner is configured or
|
|
2334
|
+
any task/release binding or plan-review authorship marker is stored, even after
|
|
2335
|
+
that configuration is removed.
|
|
2336
|
+
|
|
2337
|
+
With the lifecycle on (an `.agenthub/sdlc.toml` mode other than off), a card's planners get a "The board
|
|
2338
|
+
changed" notice (#758). The planner whose own write changed the board is skipped.
|
|
2339
|
+
A planning revision, a dependency change or a new card is a task notice; state
|
|
2340
|
+
moves, reviews and assignments are recorded at `fyi` weight (no turn), at most
|
|
2341
|
+
once per planner per ten minutes. A newer notice replaces an unsettled copy, and
|
|
2342
|
+
the hub's own bookkeeping tells nobody.
|
|
2281
2343
|
|
|
2282
2344
|
## Resetting a project's hub
|
|
2283
2345
|
|
|
@@ -2397,7 +2459,7 @@ Rows without a live process are stale registrations; forget them with
|
|
|
2397
2459
|
|
|
2398
2460
|
## Agent CLI versions
|
|
2399
2461
|
|
|
2400
|
-
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).
|
|
2462
|
+
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). Qwen has two entries: `qwen` for headless ACP and `qwen-dual` for the dual-output TUI (#286).
|
|
2401
2463
|
|
|
2402
2464
|
- `ahub agents [--json]` lists each gated CLI with its version, verdict and verified versions.
|
|
2403
2465
|
- **verified:** a receipt exists.
|
|
@@ -2409,7 +2471,7 @@ Agent CLIs update themselves often, and a hub release cannot follow every one. O
|
|
|
2409
2471
|
- 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.
|
|
2410
2472
|
- What trust cannot prove is printed when you trust.
|
|
2411
2473
|
- `ahub doctor` shows one line for each installed CLI that is not on a verified version.
|
|
2412
|
-
- 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
|
|
2474
|
+
- 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, agy and `qwen-dual` are not watched.
|
|
2413
2475
|
|
|
2414
2476
|
## Upgrade and crash recovery
|
|
2415
2477
|
|
|
@@ -2935,7 +2997,9 @@ next actions").
|
|
|
2935
2997
|
AND pid = <pid>"` (`ahub projects --json` shows the id). A
|
|
2936
2998
|
project whose directory is
|
|
2937
2999
|
gone is only recorded (`ahub doctor --orphans` lists a hub left running
|
|
2938
|
-
there). It records its decision before it acts
|
|
3000
|
+
there). It records its decision before it acts; that audit entry keeps the
|
|
3001
|
+
operation's error at that moment as `cause`, because disposal clears the
|
|
3002
|
+
error itself (#776). It releases a source hold of
|
|
2939
3003
|
its own (that hub keeps running), stops a target hub it started and has not
|
|
2940
3004
|
released (one an older coordinator started is stopped at that release's
|
|
2941
3005
|
control protocol), moves that operation's
|
|
@@ -3311,7 +3375,11 @@ protection (sandbox, text projection) is covered by its regression test. Each na
|
|
|
3311
3375
|
checkout bytes, then must fail an assertion with the corresponding guard weakened.
|
|
3312
3376
|
Seed rot (anything other than one exact replacement), a surviving seed and an
|
|
3313
3377
|
invalid detection have distinct errors. Compiler, setup, unrelated-test and timeout
|
|
3314
|
-
failures never count as detection.
|
|
3378
|
+
failures never count as detection. When the anchor text is missing, the seed-rot
|
|
3379
|
+
error also names the base commit, the symbol that held the anchor there and that
|
|
3380
|
+
symbol's current file and line, or says which part is unknown (#778). This is
|
|
3381
|
+
evidence only: the exact-match rule still fails the pair. `--base <commit>` names
|
|
3382
|
+
the base; without it the runner uses the merge base with `origin/main`.
|
|
3315
3383
|
|
|
3316
3384
|
Each seed has a private temporary checkout without Git metadata, state, output
|
|
3317
3385
|
directories or user untracked files. Installed dependency packages are linked,
|
|
@@ -3321,8 +3389,9 @@ registry directories and a scrubbed environment. The normal 20-second test timeo
|
|
|
3321
3389
|
both legs. Successful fixtures are removed; a failed pair prints its preserved
|
|
3322
3390
|
fixture location with test and leak evidence for inspection.
|
|
3323
3391
|
|
|
3324
|
-
CI runs the pairs as four Linux shards (`bun scripts/seeded-check.ts --shard i/4
|
|
3325
|
-
every fourth pair, still sequential within a shard
|
|
3392
|
+
CI runs the pairs as four Linux shards (`bun scripts/seeded-check.ts --shard i/4 --base <ref>`,
|
|
3393
|
+
every fourth pair, still sequential within a shard; the base is the PR's base commit
|
|
3394
|
+
or the push's previous one, on a full-history checkout) beside the ordinary checks; the
|
|
3326
3395
|
required job `seeded guards` passes only when all four shards passed (#457). The pairs
|
|
3327
3396
|
do not repeat on macOS or run recursively inside `bun test`. The runner reports every
|
|
3328
3397
|
pair's elapsed seconds and the total runtime. A green ordinary check alone does
|
|
@@ -3336,8 +3405,11 @@ unreadable result runs the main gate again and refuses release. A manual
|
|
|
3336
3405
|
it is never accepted as full-gate evidence. A `timing_runs=20` dispatch runs only the daemon, PII screen and ACP
|
|
3337
3406
|
test files twenty times on macOS, in its own concurrency group; it does not replace the full gate. Each PR has its own CI concurrency group, so PRs run side by side; within a PR a newer pending run replaces the older pending one and an admitted run is never cancelled; main pushes and dispatches keep queueing every run. Two groups admitting the same tree at once may run it twice, never a false green (#609). `scripts/check.sh --changed [<base>]` runs every non-test step but only the affected test files, and the full suite when it cannot tell; the full gate stays CI's (#610).
|
|
3338
3407
|
`scripts/check.sh` stops a suite still running after `AHUB_CHECK_HANG_S` seconds
|
|
3339
|
-
(960 by default); hosted CI sets 1080 on Linux
|
|
3340
|
-
|
|
3408
|
+
(960 by default); hosted CI sets 1080 on Linux inside a 25-minute job limit and 1440
|
|
3409
|
+
on macOS inside a 30-minute one (#378, #593, #752).
|
|
3410
|
+
The `closing-refs` workflow fails a PR whose title, body or commit messages would make
|
|
3411
|
+
GitHub close an issue the text only mentions (`Refs #N`, a negated or qualified keyword);
|
|
3412
|
+
an issue linked only in the sidebar passes (#760).
|
|
3341
3413
|
The gate holds `<git common dir>/ahub-heavy.lock` across every worktree of a
|
|
3342
3414
|
repository. A second gate waits up to `AHUB_CHECK_LOCK_WAIT_S` (1800 seconds by
|
|
3343
3415
|
default; 0 fails immediately) and names the holder. A holder whose PID is gone
|
|
@@ -3583,10 +3655,22 @@ The playbook lifecycle (#257, #481) is off without `.agenthub/sdlc.toml`. When e
|
|
|
3583
3655
|
## Optional Qwen Code peer
|
|
3584
3656
|
|
|
3585
3657
|
Select Qwen per project with `ahub roster add qwen`; it defaults off and is absent
|
|
3586
|
-
from default class preferences. `ahub qwen [--mode headless] [--model <alias>]`
|
|
3587
|
-
starts its ACP peer
|
|
3588
|
-
|
|
3589
|
-
|
|
3658
|
+
from default class preferences. `ahub qwen [--mode headless|tui] [--model <alias>]`
|
|
3659
|
+
starts its ACP peer (headless) or Qwen's own TUI in your terminal (below).
|
|
3660
|
+
`--print-command` previews either. `ahub stop qwen` stops the owned process group
|
|
3661
|
+
of a headless Qwen. A conductor may start the headless form only through the
|
|
3662
|
+
selected roster and existing capabilities; the TUI is always a person's start.
|
|
3663
|
+
|
|
3664
|
+
### Qwen's own TUI, driven through dual output (#286 Part 3)
|
|
3665
|
+
|
|
3666
|
+
`ahub qwen --mode tui` runs `qwen --input-file <in> --json-file <out> --mcp-config <hub server> --approval-mode default` in the terminal you ran it from. The daemon prepares the two files (mode 0600, under `<state dir>/qwen/qwen-dual/`) and returns the launch; the hub then appends one `submit` line per delivery and tails the event file from a saved offset. It needs a Qwen the dual-output compat entry verifies (`ahub agents` shows `qwen-dual`, verified 0.26.1 only; the headless `qwen` entry is separate and unchanged) and refuses another version before it creates a file. The TUI is explicit only: `ahub qwen` without `--mode` is still headless, Qwen is not a start-mode peer, and the hub never opens this terminal by itself. The TUI start is refused for an extra Qwen instance, off roster, outside a terminal, and while a headless Qwen runs (`ahub stop qwen` first); a headless start is refused while the TUI holds its terminal.
|
|
3667
|
+
|
|
3668
|
+
- What the hub does: a delivery becomes a `submit`; the last assistant message of the turn (an `assistant` event whose `stop_reason` is not `tool_use`, then `message_stop`) is shared as the answer; busy and idle follow the events. A `can_use_tool` request goes to the console approval path (`ahub permit`, the dashboard), and the hub's own tools are approved only by their exact `mcp__agent-hub__<tool>` name. If you answer a prompt in the Qwen terminal first, the hub's pending approval is withdrawn.
|
|
3669
|
+
- **Limit 1, a deny ends the turn without an answer.** Qwen emits nothing when the hub denies: it cancels the whole turn. The hub ends the turn itself, shares no answer, settles the delivery as `completed` (a deny is a known outcome, and a `needs_review` would hold every later message to Qwen until a person resolved it) and says so in a notice. A turn whose outcome is not known (Qwen exited, an Esc followed by a new prompt, an event file that became unreadable) is the one that settles `needs_review`.
|
|
3670
|
+
- **Limit 2, the hub cannot stop a Qwen turn.** The input protocol has only `submit` and `confirmation_response`, and a signal does not stop a running turn. The inactivity watchdog therefore never cancels: after `watchdog_ms` of silence it marks the turn stalled (`ahub status`, the console and the dashboard say "press Esc in the Qwen terminal") and keeps the peer busy. The hub never types into your terminal and never signals Qwen to stop a turn.
|
|
3671
|
+
- A Qwen write or shell command that names the hub state directory is refused (see [security](security.md): the input file is a prompt channel).
|
|
3672
|
+
- If the hub cannot read the event file the peer is `detached`, shown as offline with a notice, never idle: Qwen itself keeps working, and the hub reattaches when the file is readable again.
|
|
3673
|
+
- Restart: if the hub restarts while your Qwen keeps running, it reads on from its saved offset (no event twice, no launch). If Qwen is gone, `ahub qwen --mode tui` starts `qwen -r <session id>` on the same two files; the earlier submits are not replayed and the recorded answers are not shared again. Recovery never restores this terminal as a headless worker, and `ahub stop qwen` refuses: end Qwen in its own terminal.
|
|
3590
3674
|
|
|
3591
3675
|
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
|
|
3592
3676
|
is insufficient: startup verifies its native identity/version and advertised mode
|
|
@@ -3683,14 +3767,14 @@ A bundled adapter module is authorized by the person with `adapter_modules` (at
|
|
|
3683
3767
|
|
|
3684
3768
|
- 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`.
|
|
3685
3769
|
- 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.
|
|
3686
|
-
- 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`
|
|
3770
|
+
- 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. Watch is for headless Qwen; `ahub qwen --mode tui` is Qwen's own terminal (see Optional Qwen Code peer) and has no watch view.
|
|
3687
3771
|
- 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).
|
|
3688
3772
|
- Native T0 limits: [ACP watch verification](verification/2026-10-11-acp-watch-t0.md).
|
|
3689
3773
|
|
|
3690
3774
|
# Acceptance-criteria checklist (#481)
|
|
3691
3775
|
|
|
3692
3776
|
- The task reviewer/person records a head-bound `criteria` receipt with criterion ids matching the issue's AC ids, required/result fields and hashed evidence refs. This checklist belongs to the Compliance review pass. Use `ahub sdlc record <id> '<receipt JSON>'`; [schema and example](sdlc.md#acceptance-criteria-checklist).
|
|
3693
|
-
- Deliverables (#509a, docs/sdlc.md, Deliverable records): `hub_task_done` and `hub_sdlc_record` take `deliverables: [{path, format, version?}]`; the hub hashes the files itself (a claimed hash is refused), in a plain folder with no git or PR, under the owner's execution root (its own worktree for a declared worktree instance; an unproven root refuses and reads `unknown`), and a reviewer's approval is refused with `deliverable changed since it was delivered` when a file changed since delivery (the owner calls `hub_task_done` again, or the person approves the current bytes). `ahub task show <id>` shows each file's state (`unchanged`, `changed`, `missing`, `unknown`) and `changedSinceReview`; a PII task or `pii.paths` file shows id, hash and size only.
|
|
3777
|
+
- Deliverables (#509a, docs/sdlc.md, Deliverable records): `hub_task_done` and `hub_sdlc_record` take `deliverables: [{path, format, version?}]`; the hub hashes the files itself (a claimed hash is refused), in a plain folder with no git or PR, under the owner's execution root (its own worktree for a declared worktree instance; an unproven root refuses and reads `unknown`), and a reviewer's approval is refused with `deliverable changed since it was delivered` when a file changed since delivery (the owner calls `hub_task_done` again, or the person approves the current bytes). `ahub task show <id>` shows each file's state (`unchanged`, `changed`, `missing`, `unknown`) and `changedSinceReview`; a PII task or `pii.paths` file shows id, hash and size only. The person lists every task's delivered and approved files with `ahub deliverables [--task <id>] [--approved] [--check] [--json]`: without `--check` it reads the board's records and opens no file; `--check` measures them now and marks a row `changed since review`, `a file is missing` or `could not be measured`. The dashboard card shows a `Deliverables n` chip and the task sheet a Deliverables group from the same records; it shows a change only after a live check. An agent's shell is refused (#317).
|
|
3694
3778
|
- The review request lists the recorded criteria with their ids and results, and a `hub_review` unmet item that starts with a recorded id (`AC2: ...`) is recorded on the verdict as `unmetCriteria` (#507b); `ahub task show` lists those ids in the history. A task with no checklist, and a PII task, are unchanged.
|
|
3695
3779
|
- Advise shows incomplete/stale checklist blockers; enforce checks them at approval. The `criteria` gate does not need a workflow selector. Dependencies stay with `ahub task propose --after`; checklist task import is removed.
|
|
3696
3780
|
- `status <id>`, `explain <id>` and `export <id>` use the same current board/config projection. Export keeps sanitized state and source hashes, with no external text, extra authority or verification claim.
|
|
@@ -3812,8 +3896,8 @@ only after every member is approved, cancelled or moved out; it runs no tag or p
|
|
|
3812
3896
|
The dashboard shows phase progress, blocking dependencies, dates and remaining
|
|
3813
3897
|
work. Actual task dates come from execution/review/approval history, never input.
|
|
3814
3898
|
|
|
3815
|
-
Configured planners read `hub_backlog_list` and `hub_release_list`, edit
|
|
3816
|
-
`hub_backlog_plan`, and undo their own latest eligible change with
|
|
3899
|
+
Configured planners read `hub_backlog_list` and `hub_release_list`, edit the
|
|
3900
|
+
cards they plan (see "The planner") with `hub_backlog_plan`, and undo their own latest eligible change with
|
|
3817
3901
|
`hub_backlog_undo`. Catalog guidance or a caller-supplied role grants no authority.
|
|
3818
3902
|
PII cards stay stubs, reasons are screened/withheld in public history, and planning
|
|
3819
3903
|
telemetry records ids/changed fields without prose. #247 task records carry
|
|
@@ -4230,15 +4314,15 @@ From 0.12.37 reviews can rotate across fresh headless Claude and Codex reviewers
|
|
|
4230
4314
|
|
|
4231
4315
|
Start them with `ahub claude --as claude-review`, `ahub codex --as codex-review` and `ahub kimi --as kimi-review`; stop with `ahub stop <id>`. For the Claude and Codex reviewers the command asks the running hub to start the reviewer and returns: nothing runs in that terminal, it takes no launch arguments, and `--print-command` or `--dry-run` prints a hub-start note instead of a launch (#720). 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.
|
|
4232
4316
|
|
|
4233
|
-
Codex requires a verified `codex-cli` (0.146.0 or 0.
|
|
4317
|
+
Codex requires a verified `codex-cli` (0.146.0, 0.163.0 or 0.164.0) or one the person trusts on this machine, and a passing bounded runtime receipt before its model child starts. 0.146.0 and 0.163.0 passed the [2026-10-22 model-free production admission](verification/2026-10-22-codex-reviewer-isolation.md) and 0.164.0 the [2026-10-24 one](verification/2026-10-24-codex-0164-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). Each launch approves exactly `hub_review` and `hub_task_show` per tool (`approval_mode = "approve"`), never through a server-wide default: without it Codex 0.164.0 listed the tools but refused the call, so reviews ended with no verdict (#783). A model-free receipt proves the inventory, not that a verdict reaches the hub; a [model-backed 0.164.0 run](verification/2026-10-25-codex-0164-reviewer-tool-call.md) recorded one verdict through that path. 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.
|
|
4234
4318
|
|
|
4235
|
-
Kimi requires a compat-admitted Kimi Code on the hub's PATH (receipt-verified 2.2.0 and 2.3.
|
|
4319
|
+
Kimi requires a compat-admitted Kimi Code on the hub's PATH (receipt-verified 2.2.0, 2.3.0 and 2.3.1), 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](verification/2026-10-22-kimi-qwen-compat.md) and [2.3.1](verification/2026-10-25-kimi-231-reviewer-compat.md) receipts are model-free and do 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.
|
|
4236
4320
|
|
|
4237
4321
|
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.
|
|
4238
4322
|
|
|
4239
4323
|
agy is not a reviewer (person decision, 2026-10-19): it is an optional implementer peer (see [Optional Antigravity peer](#optional-antigravity-agy-peer)), and its retained reviewer slot is outside the default pool and always unavailable with `agy is an implementer peer (#485)`. A manual pool accepts only registered reviewer kinds (Claude, Codex, Kimi, agy), so local/Pi are refused. An explicit pool without declared candidates blocks for person action; an omitted pool retains legacy routing without declarations and falls back to an eligible planner when fresh candidates are exhausted. The exhausted pool walk remains recorded; without an eligible planner, the person reviews. A manual pool may name agy, or a Kimi reviewer whose preparation fails; the reason appears as an unavailable skip, and they never run or count as approval. Do not substitute plan mode for isolation.
|
|
4240
4324
|
|
|
4241
|
-
A failed start or any child ending without a saved verdict advances to the remaining eligible candidates; no quota meaning is guessed from text. A same-family fallback is a distinct fresh reviewer session. Exhaustion records `blocked: no reviewer can run`; with no explicit pool the eligible planner fallback is retained, while an explicit pool or absent eligible planner leaves person action. It never auto-approves. A per-review isolation preparation failure excludes that peer from later tasks until a verified restart. Its reason names one cause from a closed list (`version`, `binary`, `mcp_inventory`, `plugins_hooks_apps`, `sandbox_proof`, `credential_root`, `timeout`, `unknown`) with a fixed hint, on the peer's `reviewer` line in `ahub status` and in a `hub.log` line, and never a path, native CLI text or token (#722). Only the Codex preparation classifies its failures; other reviewers report `unknown`. Recovery targets must advertise `reviewer_pool` when a pool is explicitly configured or fresh reviewer instances are declared. Verdict history retains `reviewContext` and adds `reviewerFamily` and `reviewerReason` from the host.
|
|
4325
|
+
A failed start or any child ending without a saved verdict advances to the remaining eligible candidates; no quota meaning is guessed from text. A request that went stale before its child started (a new head, review revision or reviewer) is skipped with one `hub.log` line; a still-current request whose review policy changed moves on as `no_verdict`. Neither marks the reviewer unavailable (#781). A child that ends without a verdict leaves one bounded `hub.log` line: its exit code and the hub tools it called, screened like any refusal, never tool arguments or model text. Its delivery completes only once the re-offer is confirmed; an unconfirmed re-offer stays `needs_review`. A manually named reviewer's no-verdict, and one with no declared pool, goes to the person, never to an agent the person did not choose (#453). A same-family fallback is a distinct fresh reviewer session. Exhaustion records `blocked: no reviewer can run`; with no explicit pool the eligible planner fallback is retained, while an explicit pool or absent eligible planner leaves person action. It never auto-approves. A per-review isolation preparation failure excludes that peer from later tasks until a verified restart. Its reason names one cause from a closed list (`version`, `binary`, `mcp_inventory`, `plugins_hooks_apps`, `sandbox_proof`, `credential_root`, `timeout`, `unknown`) with a fixed hint, on the peer's `reviewer` line in `ahub status` and in a `hub.log` line, and never a path, native CLI text or token (#722). Only the Codex preparation classifies its failures; other reviewers report `unknown`. Recovery targets must advertise `reviewer_pool` when a pool is explicitly configured or fresh reviewer instances are declared. Verdict history retains `reviewContext` and adds `reviewerFamily` and `reviewerReason` from the host.
|
|
4242
4326
|
|
|
4243
4327
|
Fake-CLI tests and CI cover these host contracts. [Offline isolation evidence](verification/2026-10-19-reviewer-isolation.md) and fake-CLI tests do not prove an account/model review or observed network denial. Native acceptance remains a separate [manual smoke leg](smoke.md#reviewer-pool-native-legs-519-2026-10-19); existing #223 Claude behavior has no new live proof here. Kimi's authenticated fresh-verdict receipts, and its still-open interactive-TUI coexistence and usage checks, are tracked in [Kimi smoke legs](smoke.md#kimi-reviewer-and-task-bound-mcp-533).
|
|
4244
4328
|
|
|
@@ -4299,17 +4383,46 @@ reattachment or TUI detachment clears it. The notice contains fixed guidance, wi
|
|
|
4299
4383
|
|
|
4300
4384
|
The design for planner, implementer and reviewer instances per stage is in the spec section "Amendment: roles per SDLC stage (#525)". Slice 525-1 is available: role capability per kind and form, Claude channel instances as implementer or verifier in their own worktree, and `planner` refused on builtin kinds that cannot plan (pi, local and agy): an instance declaring it is refused with `this kind cannot plan`, and a `roles` entry keeps its other roles with the notice `roles.<peer>: ignored roles outside the adapter ceiling`. A configured ACP agent (`adapters`) is different: it may hold `planner` in its `roles` or in a `roles` entry and then plans like any peer, but it can never be pinned with the `planner` setting or chosen as the automatic planner, because it has no host projection (#735). Slices 525-3, 525-4 and 525-5 are available too:
|
|
4301
4385
|
|
|
4302
|
-
- 525-3: `assign()` walks the planner holders (rotation by task id over every holder, never renumbered by availability; a named planner exact; a recorded planner kept; none for a PII task) and `ahub route explain <id>` prints that walk.
|
|
4386
|
+
- 525-3: `assign()` walks the planner holders (rotation by task id over every holder, never renumbered by availability; a named planner exact; a recorded planner kept; none for a PII task) and `ahub route explain <id>` prints that walk. Task planner bindings are recorded by 525-2. A peer that accepted or finished a task never reviews it, a named reviewer and the declared reviewer pool included; when no other candidate is left the person reviews.
|
|
4303
4387
|
- 525-4: a headless Claude implementer runs one owned child per turn in its declared worktree, with a separate persisted session per task (`start_mode: "headless"`, permission `ask` or `ask-when-needed`; `never-ask` refused).
|
|
4304
4388
|
- 525-5: terminal Claude implementer instances own write-class tasks once the daemon has verified their execution root.
|
|
4305
4389
|
|
|
4306
|
-
The operator steps for 525-1, 525-4 and 525-5 are in "Additional headless peer instances" above
|
|
4307
|
-
|
|
4308
|
-
- 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.
|
|
4309
|
-
- A plan's author does not record its own plan review while another planner is available.
|
|
4390
|
+
The operator steps for 525-1, 525-4 and 525-5 are in "Additional headless peer instances" above. Slice 525-2 adds the planner settings, task/release bindings, independent plan review and recovery floor described in "The planner" above. Slice 525-6 (Codex planner-only visibility) remains separate.
|
|
4310
4391
|
|
|
4311
4392
|
## Daemon responsiveness and launch connects (#719)
|
|
4312
4393
|
|
|
4313
4394
|
Periodic peer-roster and delivery-supervision reads select pending journal metadata/rows, excluding completed payload history. Queue revision reads do not construct a recovery snapshot. Explicit queue/history commands retain terminal history. The pending-state index supports these reads without sorting historical payloads.
|
|
4314
4395
|
|
|
4315
4396
|
Native launcher connections retry transport timeouts/unclean closes with bounded backoff for at most 15 seconds, printing `hub busy, retrying` once. The ordinary control-connect timeout remains 3 seconds. An immediately unreachable listener, authentication refusals, wire mismatch and project/instance mismatch are terminal. Every retry rereads the descriptor and preserves the invocation's delegated-audit instance pin. Usage queries retain their existing catch-up budgets and report `behind` until complete; time slicing never advances beyond the last atomically folded record.
|
|
4397
|
+
|
|
4398
|
+
## amem runtime (agent-mem#13 P4)
|
|
4399
|
+
|
|
4400
|
+
The hub exact-pins @staix/agent-mem 0.7.0 for recall, curated evidence and local deterministic capture. No runtime call reaches a claude-mem worker; `memory.worker_url` is ignored. The person's `ahub memory import claude-mem` remains explicit and off by default. Existing profile, alias, PII and private-turn fences still apply. `ask --remember` and context checkpoints propose machine-local candidates, never automatic curated evidence. See [memory integration](memory.md#in-process-recall-and-capture-agent-mem13-p4) for changed behavior and bounded-view ceilings.
|
|
4401
|
+
|
|
4402
|
+
## Backlog issue identity and notes
|
|
4403
|
+
|
|
4404
|
+
The card's effective planner or the person can relink an unstarted backlog card through `hub_backlog_plan`, using `fields: {sdlc: {repo: "owner/repo", issue: 525}}`. The change is one planning revision and clears the old spec acceptance. Stage, reviewed heads, checklists and other lifecycle evidence cannot be supplied through this path; `hub_sdlc_record` still refuses backlog work.
|
|
4405
|
+
|
|
4406
|
+
Omit tool `fields`, or use `{}`, to record only the bounded reason as a new revision. The person CLI retains its JSON argument: `ahub backlog plan <id> <revision> '{}' '<reason>'`. Existing planner scope, pins, frozen releases and stale-revision checks still apply. Undo restores identity members without restoring old consent; null members represent an absent previous repo or issue.
|
|
4407
|
+
|
|
4408
|
+
The grooming digest no longer calls ordered dependency phases duplicate merely because they share a design issue. It still reports path/symbol overlap, unrelated same-issue cards and references requiring attention. It uses dependency edges only, including bounded public context for approved intermediate phases.
|
|
4409
|
+
|
|
4410
|
+
## Inspecting memory symbol anchors
|
|
4411
|
+
|
|
4412
|
+
`ahub doctor --stale-anchors [--json]` (#684 phase 3) checks a bounded set of this project's screened symbol anchors through the optional code-facts boundary. Stale means positively absent at the reported head; unavailable or ambiguous evidence stays unknown. Read the coverage/truncation fields before treating the report as complete. This command performs no note mutation or automatic repair.
|
|
4413
|
+
|
|
4414
|
+
A task completion note stores actually observed, existing symbol nodes instead of plan guesses. Earlier notes remain connected through the same reset-safe task node. Related-memory retrieval reaches those earlier notes at memory hop two; the graph's literal two-edge view shows the completion note and task node. Unknown observations are labelled and never substituted with the plan. See [canonical symbol anchors](memory.md#canonical-symbol-anchors-684-phase-3) for bounds.
|
|
4415
|
+
|
|
4416
|
+
## Code-facts inspection cleanup and lookup coverage
|
|
4417
|
+
|
|
4418
|
+
`doctor --stale-anchors` may create transient detached Git worktrees for exact-head analysis. A Ctrl-C or interrupted cleanup can leave a prunable registration. Inspect `git worktree list --porcelain`; remove or prune only an entry confirmed abandoned, through the person's normal Git maintenance. The report performs no automatic prune. Repeated optional cleanup failure is reported as unknown rather than escaping as a second error.
|
|
4419
|
+
|
|
4420
|
+
An absence row says "absent from indexed definitions". Imported package APIs/types and unsupported host qualification are not proof of removed source. Names containing `#`, `->` or `:` remain unknown. Existing raw-signature and normalized note associations are queried together without changing stored entries. See [symbol preparation and query compatibility](memory.md#symbol-preparation-and-historical-query-compatibility-684-follow-ups).
|
|
4421
|
+
|
|
4422
|
+
## Inspecting memory code neighbours
|
|
4423
|
+
|
|
4424
|
+
In the dashboard Memory view (#684 phase 4), select a symbol and enable Code neighbours. Dashed calls are read-time caller/callee evidence at the displayed commit SHA; solid note associations still come from authored metadata. Unknown, lower-bound and truncated coverage are advisory, never a proof of no callers. The accessible edge list carries the same SHA and direction. Toggle off to view the stored graph alone.
|
|
4425
|
+
|
|
4426
|
+
`hub_memory_graph` includes the same bounded derived context for symbol starts within its existing 6 KB output budget. Task briefs prioritize attached fails and decisions within `brief_items`; the console related-note count refers to that bounded selection. Code facts remain optional: no index is copied into memory, no graph edges are persisted and no PII task/turn starts a query.
|
|
4427
|
+
|
|
4428
|
+
Optional code work runs only while Memory is open and visible. A cold console count reports unknown immediately; it does not prepare code facts. Direct task memory remains available when optional code facts are ineligible, interrupted or unavailable. Review/completion queries pre-empt optional native work after its owned process/tree cleanup. Unknown lookups have a five-second retry floor; topology caches are commit-bound and note bodies are refreshed under current policy. These are advisory coverage bounds, not empty-result proofs.
|
package/docs/quickstart.md
CHANGED
|
@@ -17,7 +17,7 @@ ahub setup # installs the Claude Code channel plu
|
|
|
17
17
|
Or use the matching GitHub release:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
bun add -g github:STAIxBWLB/agent-hub#v0.
|
|
20
|
+
bun add -g github:STAIxBWLB/agent-hub#v0.17.0
|
|
21
21
|
ahub setup
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -30,6 +30,14 @@ and upgrade or crash recovery, see the [operations guide](operations.md). To
|
|
|
30
30
|
move running projects to a newer release later, run `ahub upgrade` in a
|
|
31
31
|
terminal: it reviews the plan with you, applies it and follows it.
|
|
32
32
|
|
|
33
|
+
## Upgrading to 0.17.0
|
|
34
|
+
|
|
35
|
+
`ahub qwen --mode tui` runs Qwen Code's own TUI in your terminal, driven by the hub through its dual-output files (#286). It is opt-in: the hub never opens it by itself, `roster.qwen` stays off by default, and headless Qwen works as before. It needs Qwen Code 0.26.1 (a new `qwen-dual` compat entry; the headless entry is not widened), refuses an extra instance (`--as`) and refuses while a headless Qwen runs (`ahub stop qwen` first). It has two limits: a hub deny ends the turn without an answer (the delivery completes, so later messages still reach Qwen), and a stalled turn is never cancelled; the hub reports it and you press Esc in the Qwen terminal. `ahub stop qwen` does not end the TUI, and `ahub upgrade` and recovery do not restore it: end it in its terminal before you upgrade, then run `ahub qwen --mode tui` again, which resumes its session. The `codex-review` reviewer now approves exactly `hub_review` and `hub_task_show`, per tool: on Codex 0.164.0 `exec` refused every MCP tool call, so its reviews ended without a verdict (#783). A reviewer turn that still ends without a verdict leaves one screened `hub.log` line (exit code and the hub tools it called) and is offered on, or to you when you named that reviewer (#453). A stale review request that the hub refuses at admission no longer marks the reviewer unavailable: a request whose binding changed is skipped, and one whose policy changed is rerouted as no verdict (#781). An unavailable reviewer slot no longer stops the agy TUI from reading its own task (#794). An `ahub recovery dispose --stop-and-archive` audit entry now keeps the error that blocked the upgrade as `cause` (#776). A task counts toward a recurring finding only where that finding was recorded open or accepted, so a fix-only record no longer files a "Review policy amendment" card (#328), and a missing generation sync remote no longer logs a failure every sync interval (#401). Upgrade running hubs with `ahub upgrade` and restart Claude sessions so they load the 0.17.0 plugin. Coming from 0.15.0 or older, the notes below apply too.
|
|
36
|
+
|
|
37
|
+
## Upgrading to 0.16.0
|
|
38
|
+
|
|
39
|
+
Always-ask now covers the local worker, Pi and Codex too (#636 slice 3): a local or Pi model tool call is classed before its permission mode, a `never-ask` grant, Pi's `Always allow` or `--unattended`, and a classed command approval request that Codex sends offers only allow-once, deny and the class budget. Unattended local or Pi work that publishes, installs or deletes now waits for you: answer it in the console, or change `action_policy` as in the 0.15.0 notes below. `ahub status` still lists Codex as not enforceable, because its native policy can run a command without sending a request, and Jcode as having no hub approval path. An approval whose command is cut or withheld (an ACP peer's private turn, for one) can only be denied, and a local `action_policy` that weakens the defaults is flagged on every status policy row. The classifier now reads the literal words around a shell expansion (`git push origin $B` asks) and takes the strictest class where the expansion can change it, while a `gh api graphql` call with one literal query no longer asks (#762, #756; see [security notes](security.md)). The hub no longer calls a claude-mem worker (agent-mem#13 P4): recall, briefs, `ahub ask` and the local worker's capture run in process on the exact-pinned `@staix/agent-mem` 0.7.0, `memory.worker_url` is ignored, `ahub doctor` reports the library, and `ahub ask --remember` and context checkpoints save pending candidates that only a person accepts; `ahub memory import claude-mem` stays the explicit way to copy old notes. The planner setting takes up to eight peers (`ahub settings set planner claude,codex`): each new task records one of them, only that planner or you change its planning, an agent's own plan is reviewed by another holder whenever one is online, and `ahub task assign <id> <peer> --role planner` moves it (#525-2; see [the planner](operations.md#the-planner-455)). Once a planner list is set or any task records a planner, `ahub upgrade` and recovery refuse a target release without `task_planners`, so the project cannot be moved back to 0.15.0 that way. `ahub deliverables [--task <id>] [--approved] [--check]` lists what each task delivered and a reviewer approved, and a dashboard card shows a `Deliverables n` chip (#509b). `ahub budget` prints each window's kind and source and says why a peer has no number (#285). The dashboard Memory view gains a Code neighbours toggle for a selected symbol, and `ahub doctor --stale-anchors` is a read-only report of memory symbol anchors at the current head (#684). The `codex-review` reviewer on Codex 0.164.0 no longer needs `ahub agents trust` (#757). Upgrade running hubs with `ahub upgrade` and restart Claude sessions so they load the 0.16.0 plugin. Coming from 0.14.0 or older, the notes below apply too.
|
|
40
|
+
|
|
33
41
|
## Upgrading to 0.15.0
|
|
34
42
|
|
|
35
43
|
Publish, external-write, destroy and install calls now ask a person (#636 slice 2): the Claude PreToolUse hook returns `ask` for such a call in every permission mode, `never-ask` included, and a hub-owned ACP peer such as Kimi in native `ask` mode never auto-approves one, not under `--unattended` either; it waits in the console and the dashboard as `Action approval (<classes>): <command>` and is denied when `approvals.timeout_s` passes. When a class budget is above one, the approval of a classed ACP call also offers `Allow <class> xN for this session`. Unattended work that publishes, installs or deletes now stops for you: answer it, or set `ahub settings set action_policy.enabled false` or `action_policy.budgets.<class> <n>` (the policy and its budgets live only in untracked `.agenthub/config.local.json`). `ahub status` names each peer where the hub cannot see the call before it runs: a Kimi in `yolo` or `auto`, a Claude session that has not run the hub's permission hook, an `--unattended` Claude launch, and Codex, Pi and the local worker until #313 (see [always-ask action policy](operations.md#always-ask-action-policy-foundation-636)). A terminal Claude instance declared with `implementer` or `verifier` and its own `worktree` now owns write-class tasks once the daemon verifies its launch record and channel cwd; start it again with `ahub claude --as <id>` after the upgrade, because a launch recorded without its execution root attaches without isolation and gets no write task (#525-5). A headless Claude implementer can be declared in `.agenthub/config.local.json` (`"start_mode": "headless"`, roles `["implementer"]`, its own registered `worktree`, `permission_mode` `ask` or `ask-when-needed`; `never-ask` is refused): create and register the worktree first, then `ahub claude --as <id>` asks the hub to start it and returns. It keeps one session per task, and its writes and shell calls reach you as allow-once or deny requests in the console; no answer is a deny (#525-4; see [additional headless peer instances](operations.md#additional-headless-peer-instances)). `hub_task_done` and `hub_sdlc_record` take `deliverables: [{path, format, version?}]`: the hub hashes the files itself, a reviewer's approval is refused when a file changed since delivery, and `ahub task show` reports each file as `unchanged`, `changed`, `missing` or `unknown` (#509; see [deliverable records](sdlc.md#deliverable-records-509a)). A review request lists the task's recorded acceptance criteria by id, and an unmet item that starts with one (`AC2: what is missing`) is recorded on the verdict (#507). A peer that accepted or finished a task no longer reviews it; when no other reviewer is left, you review it, and `ahub route explain <id>` also prints the planner walk (#525-3). Instances, `review`, `snapshots.keep`, `approvals.timeout_s`, `context.gate` and the `sdlc.toml` `mode` and `required_checks` can be edited with `ahub settings edit`, the console Settings key `c` or the Structure group of an `ahub ui --settings` session: the hub validates, shows a diff and keeps a backup; a changed instance or `sdlc.toml` waits for a hub restart (console `R`), and keys that run code or locate secrets stay console only with their name typed (#689; see [structural configuration](operations.md#structural-configuration-from-the-console-and-the-dashboard-issue-689)). Kimi's token use is now counted from its session wire log, so a `budget.kimi_tokens_5h` you set pauses Kimi when it is reached (#285). `ahub backlog list` prints a table by rank; a script that read its output uses `--json` (#399). A launcher that meets a busy hub retries for up to 15 s and prints `hub busy, retrying` once (#719). Upgrade running hubs with `ahub upgrade` before relying on deliverables: an older daemon drops them from a newer plugin's `hub_task_done` without a word. Restart Claude sessions so they load the 0.15.0 plugin, and if `ahub status` shows a fresh reviewer instance such as `codex-review` stopped after the upgrade, start it again with `ahub codex --as codex-review`. Coming from 0.13.0 or older, the notes below apply too.
|
|
@@ -88,7 +96,7 @@ The 0.12.38 plugin reports a reply stopped by the hop cap as not delivered inste
|
|
|
88
96
|
|
|
89
97
|
Antigravity (`agy`) can join as an optional pull-only implementer (#485). It is off roster by default: install the Antigravity CLI 1.4.x (1.4.2 verified; other 1.4.x patches launch with a warning; on 1.4.3 the hub tools appear from the second TUI turn), run `ahub roster add agy`, then run `ahub agy` in a terminal. Its native permissions are unmanaged and it has no hub sandbox. See [Antigravity operations](operations.md#optional-antigravity-agy-peer).
|
|
90
98
|
|
|
91
|
-
Reviews can rotate across fresh Claude, Codex and Kimi reviewer sessions (#519, #533). Declare headless reviewer-only instances in `.agenthub/config.local.json`; Codex and Kimi join only with `review_mode: "fresh"`. Codex also needs a compat-admitted Codex (receipt-verified 0.146.0 and 0.163.0; select it with `codex_bin` when needed), and Kimi needs a compat-admitted Kimi Code on PATH (receipt-verified 2.2.0 and 2.3.
|
|
99
|
+
Reviews can rotate across fresh Claude, Codex and Kimi reviewer sessions (#519, #533). Declare headless reviewer-only instances in `.agenthub/config.local.json`; Codex and Kimi join only with `review_mode: "fresh"`. Codex also needs a compat-admitted Codex (receipt-verified 0.146.0 and 0.163.0; select it with `codex_bin` when needed), and Kimi needs a compat-admitted Kimi Code on PATH (receipt-verified 2.2.0, 2.3.0 and 2.3.1), signed in with its own OAuth login. Run `ahub agents` for the current version policy; every fresh reviewer still needs a passing runtime preparation. The [2.3.0](verification/2026-10-22-kimi-qwen-compat.md) and [2.3.1](verification/2026-10-25-kimi-231-reviewer-compat.md) receipts are model-free and do not establish real login or model readiness. A headless reviewer instance without `review_mode` keeps its native behavior and stays out of the pool. agy is not a reviewer: naming it in `review.pool` shows an unavailable skip in `ahub route explain`, never a review. Once a train is active or frozen, or `review.pool` is set or fresh reviewer instances are declared, `ahub upgrade` refuses a target release without that support, so an older release cannot take the project over. See [fresh reviewer pool](operations.md#fresh-reviewer-pool-519).
|
|
92
100
|
|
|
93
101
|
A guarded config edit that the hub keeps at its running value now shows as `config retained: <keys>; run ahub settings reload` in status, the console and the dashboard's Settings, and starting a peer whose launch keys are retained says it uses the running value (#542). See [settings](operations.md#settings-from-the-dashboard-and-the-terminal).
|
|
94
102
|
|
|
@@ -98,7 +106,7 @@ The restarted Claude planner gets the release-train tools (`hub_release_new`, `h
|
|
|
98
106
|
|
|
99
107
|
Jcode must be 0.98.0 or later, below 1.0.0; 0.94.0 is no longer accepted, so `ahub doctor` fails its Jcode row for an older install and the peer does not start (#529). Every owned jcode process runs with `JCODE_NO_TELEMETRY=1`.
|
|
100
108
|
|
|
101
|
-
Since 0.12.37 the hub
|
|
109
|
+
Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.7.0. Before anyone runs `amem migrate --shards` on a memory home, every hub using that home must run 0.12.37 or later: an older hub does not see the split and keeps writing the old layout. `ahub memory profile-check` is split-aware and compares each hub with its own project's shard (#536). See [memory profiles and rollout](memory.md#selected-memory-profile).
|
|
102
110
|
|
|
103
111
|
From 0.12.30 or earlier, existing Jcode project MCP entries need one refresh before conductor or dashboard starts. Once per project, the person runs:
|
|
104
112
|
|
|
@@ -150,7 +158,7 @@ or set `OMNIROUTE_API_KEY`. The `.agenthub/routing.toml` that `ahub init` writes
|
|
|
150
158
|
| `ahub task propose [--class <c>] <title>` | put work on the board; the hub picks an owner and a reviewer, and the class if you name none |
|
|
151
159
|
| `ahub board` | who has what, one line per task at a terminal width; `--full` for whole titles and SDLC advice, `ahub task show <id>` for one task |
|
|
152
160
|
| `ahub task cancel <id> --reason <text>` | close obsolete work without approving it or stopping a native turn |
|
|
153
|
-
| `ahub settings set planner <peer
|
|
161
|
+
| `ahub settings set planner <peer>[,<peer>...]` | pin up to eight planners; status reports whether they came from settings, roles or the automatic choice |
|
|
154
162
|
| `ahub settings reload` | apply edited config files without a restart; guarded values wait for your `y` in this terminal, and restart-only keys stay pending |
|
|
155
163
|
| `ahub settings edit <file> set <path> <json>` | change an instance, the review block or the `sdlc.toml` lifecycle with a validated diff and a backup; `ahub settings backups` lists the backups |
|
|
156
164
|
| `ahub status` | peers, queues, pauses; `ahub budget` for quota windows |
|
|
@@ -165,7 +173,7 @@ More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-de
|
|
|
165
173
|
|
|
166
174
|
## Shared memory
|
|
167
175
|
|
|
168
|
-
The hub exact-pins the first-party `@staix/agent-mem` 0.
|
|
176
|
+
The hub exact-pins the first-party `@staix/agent-mem` 0.7.0 core, including deterministic capture; no claude-mem worker is needed. Existing shared-v1 memory remains the default; upgrading does not migrate it. Managed agents use screened `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools, or propose a correction with `hub_memory_correct`; only a person accepts candidates through the supported `amem review` path. Since agent-mem 0.7.0, `amem review` also accepts candidates on a selected generation.
|
|
169
177
|
|
|
170
178
|
Before any real generation migration, upgrade every hub sharing that memory home to 0.12.30 or later and check its authenticated binding with `ahub memory profile-check` in each custom registry. Ready bindings prove compatibility, not an atomic live cutover: quiesce consumers and close their handles before migrating, then reopen through the supported session-preserving lifecycle. Invalid or changed profiles disable native memory without falling back to legacy writes; the bus and board continue. See [memory operations](operations.md#hub-memory) for the remaining rollout gates.
|
|
171
179
|
|
package/docs/roles.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Role catalog (#295)
|
|
2
2
|
|
|
3
3
|
- Flow roles remain conductor, planner, implementer, verifier and reviewer. Only the existing `roles` block controls their authority and routing. Catalog roles are bounded guidance selected through `catalog_roles`; they add no tool, capability, permission mode, sandbox reach or routing preference.
|
|
4
|
+
- Reviewer completion (#784, this repository): the reviewer that approves a PR at its head merges it once exact-head CI is green, no review thread is unresolved and no change request is pending, then removes the branch and worktree, or names the open gate. A release PR waits for the person's release consent. This is this repository's convention (its `AGENTS.md`, outside the managed block), not a shipped default: the AGENTS block template, the catalog roles and the flow role contracts are unchanged, so another project keeps merge with the person unless its own AGENTS.md delegates it.
|
|
4
5
|
- Default catalog assignments are absent. Existing flow contracts are byte-identical to main d83cb8dd when no catalog role is selected.
|
|
5
6
|
|
|
6
7
|
# Definitions and layers
|