@staix/agent-hub 0.28.0 → 0.30.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 +22 -0
- package/README.md +5 -3
- package/docs/agent-notes/README.md +12 -0
- package/docs/agent-notes/adapters.md +2 -1
- package/docs/agent-notes/bus.md +1 -0
- package/docs/agent-notes/daemon.md +4 -1
- package/docs/agent-notes/local-worker.md +3 -1
- package/docs/agent-notes/tasks.md +7 -3
- package/docs/agent-notes/tests.md +3 -0
- package/docs/design/adapters.md +56 -0
- package/docs/design/agent-hub-architecture.md +12 -0
- package/docs/design/bus.md +8 -0
- package/docs/design/task-board.md +19 -1
- package/docs/dogfood.md +13 -7
- package/docs/operations.md +177 -20
- package/docs/quickstart.md +18 -3
- package/docs/sdlc.md +2 -2
- package/docs/security.md +45 -4
- package/docs/smoke.md +13 -2
- package/docs/specs/2026-10-12-office-view-design.md +86 -3
- package/docs/verification/2026-11-03-0.29.0.md +59 -0
- package/docs/verification/2026-11-03-0.30.0.md +54 -0
- package/docs/verification/2026-11-03-agy-1.4.12-launcher-nonce.md +42 -0
- package/docs/verification/2026-11-03-agy-1.4.12.md +90 -0
- package/docs/verification/2026-11-03-agy-tui-close.md +49 -0
- package/docs/verification/2026-11-03-control-write-stall-windows.json +241 -0
- package/docs/verification/2026-11-03-control-write-stall-windows.md +20 -0
- package/docs/verification/2026-11-03-grok-1.0.62-t0.md +150 -0
- package/docs/verification/2026-11-03-live-board-latency.json +556 -0
- package/docs/verification/2026-11-03-live-board-latency.md +64 -0
- package/docs/verification/2026-11-03-pi-150-compat.md +40 -0
- package/docs/verification/2026-11-03-pi-title-api.md +26 -0
- package/docs/verification/2026-11-03-qwen-0265-acp.md +55 -0
- package/docs/verification/2026-11-03-qwen-0265-dual-output.md +40 -0
- package/docs/verification/dogfood/2026-11-03.md +3095 -0
- package/docs/verification/pi-150-model-free.ts +57 -0
- package/docs/verification/pi-150-native.mjs +21 -0
- package/docs/verification/pi-150-title-api.mjs +31 -0
- package/docs/verified.json +14 -14
- package/package.json +2 -2
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +715 -45
- package/src/adapters/compat.ts +10 -10
- package/src/adapters/definitions/builtin-metadata.ts +2 -2
- package/src/adapters/local-worker.ts +22 -6
- package/src/adapters/pi.ts +92 -10
- package/src/adapters/registry-types.ts +4 -0
- package/src/adapters/registry.ts +2 -0
- package/src/cli/autonomy.ts +66 -1
- package/src/cli/console-state.ts +6 -2
- package/src/cli/help.ts +3 -1
- package/src/cli/identity.ts +8 -1
- package/src/cli/main.ts +39 -0
- package/src/cli/output.ts +5 -0
- package/src/cli/recovery-package.ts +9 -0
- package/src/cli/worktree-tidy.ts +158 -0
- package/src/cli/worktrees-output.ts +43 -0
- package/src/hub/board.ts +31 -5
- package/src/hub/bus.ts +4 -4
- package/src/hub/conductor.ts +4 -3
- package/src/hub/config-apply.ts +2 -1
- package/src/hub/control-client.ts +16 -1
- package/src/hub/control-write-trace.ts +409 -0
- package/src/hub/daemon.ts +408 -66
- package/src/hub/dogfood-read.ts +62 -9
- package/src/hub/hub-tools.ts +12 -6
- package/src/hub/manager.ts +9 -1
- package/src/hub/peer-doing.ts +33 -3
- package/src/hub/peers.ts +7 -0
- package/src/hub/routing.ts +9 -2
- package/src/hub/runtime-capture-prune.ts +4 -1
- package/src/hub/sdlc-release-authorization.ts +13 -4
- package/src/hub/sdlc-release.ts +23 -10
- package/src/hub/sdlc.ts +15 -2
- package/src/hub/settings.ts +3 -0
- package/src/hub/task-worktree.ts +331 -0
- package/src/hub/tasks.ts +192 -25
- package/src/hub/ui.ts +2 -0
- package/src/hub/worktree-prs.ts +100 -0
- package/src/hub/worktree-shelf.ts +246 -0
- package/src/local/deny.ts +49 -0
- package/src/local/tools.ts +4 -2
- package/src/memory/brief.ts +5 -0
- package/src/memory/capture.ts +1 -1
- package/src/memory/client.ts +5 -2
- package/src/pi/extension.ts +43 -3
- package/src/ui/index.html +133 -10
- package/src/ui/office-model.ts +64 -8
- package/src/ui/office-space.ts +1 -0
- package/src/ui/plugin.ts +14 -3
package/docs/dogfood.md
CHANGED
|
@@ -13,12 +13,13 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
13
13
|
| Distinguishable sessions and sender provenance (#1036, `session_identity`) | on after release and upgrade: a connection that names a peer id but is not that peer's current session is a distinct `<peer>~<origin>` session that can send and read, holds none of the peer's roles and replaces nobody; the channel plugin binds to its own project; every envelope and attach event records the connection. Nothing is refused to a connection that worked before. The recovery label `session_identity` applies once an unsettled delivery holds a session's message | `grep '"session":true' .agenthub/state/events.jsonl` lists every message a foreign session sent, with its minted id and no path or text; a recipient's header shows `from "claude~<id>"` for it; test/identity-provenance.test.ts (AC1, AC3, AC4, recovery label) and test/identity-channel-project.test.ts (AC2, real plugin against a new and an old hub) hold it. Not authentication: a same-user process can always act as the user |
|
|
14
14
|
| Cross-project task handoff with state follow-back (#604, `task_handoff`) | on after release and upgrade: `ahub task handoff` and `hub_task_handoff` register work for another registered project that runs agent-hub on this machine as an ownerless proposal on its board; the requesting peer is told each state change as a `kind: task` message. Nothing is queued, and the origin has no authority there | `ahub board --handoffs` lists what this project handed over with the last state each target reported; `ahub board` and `ahub task show` in the target name the origin project and peer; test/handoff-daemon.test.ts runs two real daemons (AC1 to AC5 and the recovery label), test/handoff-core.test.ts and test/handoff-board.test.ts hold the pure core and the tables |
|
|
15
15
|
| Staged project upgrades (#1039) | off: available for the person to upgrade projects independently; this development hub is not upgraded by a fixture | test/published-protocol-compat.test.ts uses the published 0.25.0 client/plugin and reverse daemon; test/staged-upgrade.test.ts checks independent holds and scoped effects; test/staged-runtime-daemon.test.ts checks a real release-root daemon after mutable install removal; test/board-schema-guard.test.ts checks named pre-effect refusal and WAL metadata; `test/project-runtime.test.ts` and `test/project-runtime-lifecycle.test.ts` cover updated resolver retention/refusal and real lifecycle/dashboard routing with synthetic captured daemons; `test/runtime-capture-prune.test.ts` covers references, bounded retention and publication races; `test/upgrade-stopped-project.test.ts` verifies no preservation for stopped projects. These fixtures do not prove published pre-0.26 CLI behavior |
|
|
16
|
-
| Approval head binding and re-review (#1047) |
|
|
16
|
+
| Approval head binding and re-review (#1047, #1121) | source/fixture coverage; the #1121 stale-head protections and actionable refusals await release and upgrade; live re-file verification not run | `test/review-head-binding.test.ts` covers both-head refusals, moved-PR commitless re-files and omitted-head stale approvals; `test/task-review-refile.test.ts` covers owner re-submit, reviewer withdrawal, legacy verdict heads, merged/cancelled refusals and held-screen races; `test/sdlc-queue.test.ts` and `test/sdlc-merge.test.ts` reject stale approval at queue and dispatch. `ahub task show <id> --json` exposes `approval.head`, `latestHead`, `mismatch` and `current`; verdict history retains `reviewedHead` |
|
|
17
17
|
| Default agent set started by `ahub up` (#608, `start.agents`) | off here: this repository's agents are started by their own terminals; it is a machine-local setting and a committed config cannot turn it on. On for a person who runs `ahub setup` and `ahub up` on a project that lists agents. | each `ahub up` prints one line per agent (started, already attached, or the refusal with the manual command); the `peer_start` replies in `hub.log` and the terminal provider's recorded starts show whether a listed agent attached, and `ahub status` shows its state after |
|
|
18
18
|
| `ahub down` (counterpart of `ahub up`) | on: an alias of `ahub kill` for stopping this project's hub | the person stops the hub with `ahub down` and `ahub status` then reports it stopped; test/identity.test.ts keeps it person-only (`console`) and labelled `down`, and test/help.test.ts holds its help entry |
|
|
19
19
|
| Encrypted rooms (#446 X1) | off; source-only crypto/wire, with no broker, room link, invitation CLI or delivery enabled | real WebCrypto vectors and negative wire fixtures; atomic memory fake ports establish ordering only; durable X3 state and the X7 two-machine person receipt remain unverified |
|
|
20
20
|
| Blind room broker (#446 X2) | off; standalone source/fixture work, no public TLS service or hub room link configured here | fake-client auth/fan-out/revocation/restart, ciphertext-only child-process canary, owner admission/offline room reset, queue caps/TTL/FIFO/migration, safe directory modes, and person-only CLI tests; live proxy/account/X7 receipts remain unverified |
|
|
21
21
|
| Room membership and presence (#446 X3) | off; no person room enrollment or exposure configured here | isolated fake-hub/broker tests for OOB enrollment, MITM refusal, durable sequence/replay/grace, explicit fingerprint confirmation/abort, refused-frame retirement, exposure revocation and ids-only presence; room list/status for ids and link state; X4 chat and X7 two-machine live receipt remain separate and unverified |
|
|
22
|
+
| Worktree shelf (#1057): `ahub worktrees`, `tidy`, `tidy --confirm <fingerprint>`, the Agents panel section, Park/Pin, the explicit PR refresh and the inbox alert | fixture-only until a person uses it, and only after release and upgrade: this repository keeps every task in `.worktrees/<name>`, so it is the first real use, but nothing here has run `tidy --confirm` yet, and `worktrees.quiet_days` stays 7 until the owner has used it for a week | `ahub worktrees` live and settled counts over a week, and how many settled rows a person then Pins (a Pin means a rule was wrong); `tidy` preview refusals by reason (`task not approved or cancelled`, `unpushed commits`, `branch changed since preview`); after a confirm, `git worktree list` against the preview; test/worktree-shelf.test.ts, test/worktree-tidy.test.ts and test/worktree-panel.test.ts (a PII row stays live and redacted, a branch switch refuses, no GitHub call on a read, the daemon removes nothing) |
|
|
22
23
|
| Message bus, digests, priorities | on | `ahub report`: messages, digests, overflow, undeliverable; delivery latency from events |
|
|
23
24
|
| Control-send recipient normalization (#963) | active after release and hub upgrade; this PR does not change the running hub | string recipients reach only the named peer, invalid shapes publish nothing, omitted/empty arrays preserve broadcast; real native recipient behavior remains unverified |
|
|
24
25
|
| Compact board (#724) | on | `ahub board` at 80, 120 and 200 columns: one line per task (test/board-compact.test.ts) |
|
|
@@ -46,7 +47,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
46
47
|
| Codex planner sandbox and role visibility (#525-6) | source/fixture coverage after merge and release; six declared planner/implementer/reviewer instances are not configured here, and the person live leg is unverified | fake thread-start/resume read-only confirmation and refusal before adoption; planner-only Claude mutating-tool grants withheld; status form/capable roles/isolation and task planner/holder-reason parity across CLI, console, dashboard and explain; the native six-instance receipt in `docs/smoke.md` is recorded separately when run |
|
|
47
48
|
| Floor policy (#999 T3, `action_policy.floor`) | source and test after merge and release; off here (a person turns it on in the untracked `config.local.json`), and the running hub takes it after upgrade | `test/action-floor.test.ts` (every allowed, asked and opaque case, status guard rows) and `test/daemon-action-floor.test.ts` (the Pi permit path through the real daemon: allowed calls run with no prompt, force and default-branch pushes, tags, `gh release`, `--admin` and other repositories ask); T4's live receipt records it under Orca |
|
|
48
49
|
| Confirmation-point inventory (#999 T0) | source and test coverage; `ahub autonomy status` reads the inventory after this feature is released, with no default prompt change from the data alone | `test/confirmation-matrix.test.ts`: every adapter-catalog kind has a tool-approval and a classed-action row per environment, kinds facts equal the definitions, cited source lines exist; the `unknown` rows are the list T4's live receipt must close |
|
|
49
|
-
| Project autonomy preset (#999 T1) | off on this repository until released and explicitly enabled by the person; project scope only | focused person-only, retained-consent, metadata-independent off and authenticated/fallback preset undo tests; the preset writes `action_policy.floor` (#999 T3) and off removes it; status
|
|
50
|
+
| Project autonomy preset (#999 T1) | off on this repository until released and explicitly enabled by the person; project scope only | focused person-only, retained-consent, metadata-independent off and authenticated/fallback preset undo tests; the preset writes `action_policy.floor` (#999 T3) and off removes it; status leads with a peer table separating current modes from desired defaults, groups identical floor verdicts and unknowns once with peer lists (#1137), and reads each floor class from the host verdict (`floorEnforcement`), naming the unverified guard where the hub does not see the call first; the Orca zero-prompt native task remains T4 |
|
|
50
51
|
| Machine autonomy and used Claude homes (#999 T2) | off until released and explicitly opted in by the person; no real home is changed by fixture tests | trusted-default/unsafe-default startup consent, all-project preview/apply, init inheritance with unchanged absent-file ask defaults, and isolated per-home plugin/hook setup/status tests; #1069 covers preserving project/local plugin rows while configuring only user scope, plus recording `start.agents` after a failed home step; metric: applied/refused registered targets and missing/unknown discovered-home states; native Orca receipt remains T4 |
|
|
51
52
|
| Read-time memory code neighbours (#684 phase 4) | off until released; dashboard toggle is opt-in | derived call edges with current SHA; attached fail/decision brief coverage; explicit unknown/truncated results; unchanged authoritative memory log bytes |
|
|
52
53
|
| Canonical memory symbol anchors (#684 phase 3) | off until released; optional `doctor --stale-anchors` report only | actual-symbol completion anchors versus plan guesses; symbol-related earlier notes at memory hop two; stale/unknown/truncated report counts; zero note mutations during inspection |
|
|
@@ -87,7 +88,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
87
88
|
| Merge-time PR readback, release metrics and security-scan baseline (#481 S7, AC12) | source and fixture coverage with a fake gh and real train transitions; the readback is on wherever auto merge is `on`, release metrics need shipped trains with recorded history, and the security scan and its bands stay off here until `[security_scan]` and `[bands.security_open_alerts]` are set | `cost` on merge records, `ahub sdlc metrics` review/CI-at-merge rows, the releases row of `ahub sdlc release`, `security_scans` rows and `security_open_alerts` cards |
|
|
88
89
|
| Required checks | advise (`check (ubuntu-latest)`, `check (macos-latest)`, `seeded guards`) | first-pass CI rate, same-head reruns (`hub_sdlc_costs`) |
|
|
89
90
|
| Seed anchor diagnostics (#684) | on in the seeded checker; exact-match failure remains mandatory | missing anchors report the base commit, enclosing symbol and current file/line or explicit unknown; `test/seeded-check.test.ts` |
|
|
90
|
-
| Release authorization (#481 S6, #1063) | fixture coverage; delegated live consent awaits release and project upgrade | `test/sdlc-release-authorization.test.ts` and flow fixtures retain exact candidate/docs/origin/restart bindings and record the actual user/conductor actor; agent-read and floor fixtures refuse other peers, private turns and live-test; no fixture authorizes a live release |
|
|
91
|
+
| Release authorization (#481 S6, #1063, #1120) | fixture coverage; delegated live consent awaits release and project upgrade | `test/sdlc-release-authorization.test.ts` and flow fixtures retain exact candidate/docs/origin/restart bindings and record the actual user/conductor actor; agent-read and floor fixtures refuse other peers, private turns and live-test; `test/runtime-capture-checker.test.ts` proves a real capture carries the documentation checker and that a missing or failing one is refused as its own cause, not as stale documentation; no fixture authorizes a live release |
|
|
91
92
|
| SDLC metrics and control bands (#481 S7) | `ahub sdlc metrics` on; bands off until `[bands]` is set in `.agenthub/sdlc.toml`, and they write cards only in advise or enforce (in off the report still shows tiers). Completion checks are off here, so `first_pass_check` and the PR-based figures read unknown | its own report; breach episodes per week by tier, and band cards the planner accepted rather than dropped |
|
|
92
93
|
| Fresh headless reviewers (#223, #519) | configured here (`codex-review`); per-tool approval correction and no-verdict diagnostics/re-offer (#783) take effect after release and upgrade | reviews by fresh sessions, findings they add; a per-review start failure names a closed cause class (#722): `ahub status` reviewer line and hub.log `[cause: ...]`, with the share of failures that are `unknown`; stale admission skips and current-policy `no_verdict` reroutes leave the reviewer available (#781); a real `hub_review` verdict per verified backend/version, beyond inventory-only proof; bounded refusal diagnostics, confirmed re-offers without queue holds, and uncertain fallback holds |
|
|
93
94
|
| Completion checks per class | off: the implementer already runs `scripts/check.sh`; a hub-run copy would double the heavy-slot use | time to verdict when on |
|
|
@@ -99,8 +100,8 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
99
100
|
| amem runtime integration (agent-mem#13 P4) | on after release; no claude-mem worker dependency | no-worker tripwire requests (must be 0), screened capture rows, profile refusals, all-author short-term recall, bounded-view truncation notices and curated-only ask citations |
|
|
100
101
|
| Shared memory through amem, briefs, recall preface | on; library intent briefs and plan guard (#436) take effect after release and hub upgrade; legacy index/timeline reads and worker notices retire in intent mode | notes saved per week, brief hits, fails that prevented a retry; same-input hub/library brief equality, host privacy refusals and front-of-brief plan fails despite the library byte cap or standalone screen |
|
|
101
102
|
| `ahub ask` | on | answers with cited ids |
|
|
102
|
-
| Source registry, `ahub source add\|list` (#508 AC1, AC2, AC5 CLI) | on after release; local (no daemon needed for the person); `add` is the person's or the configured conductor's (#933, admitted and audited by the hub); `hub_source_read` adds bounded, screened snapshots and private stubs; plan
|
|
103
|
-
| Intake drafts, `ahub intake` (#511 AC1 CLI, AC2 to AC4) | on after release; person-only except `approve`, which the configured conductor may run too (#933); a draft is held until `ahub intake approve`, so nothing changes for work that does not use it; the dashboard
|
|
103
|
+
| Source registry, `ahub source add\|list` (#508 AC1, AC2, AC5 CLI) | on after release; local (no daemon needed for the person); `add` is the person's or the configured conductor's (#933, admitted and audited by the hub); `hub_source_read` adds bounded, screened snapshots and private stubs; plan sources are registry-validated on proposal/acceptance, and the dashboard Plan sheet lists allowlisted source metadata (#1144) | `ahub source list` rows (id, size, private, origins); `sources/` under the hub state dir; a refusal in the CLI audit for an agent shell; unknown-plan-source refusals and metadata-only dashboard snapshot tests (#1144) |
|
|
104
|
+
| Intake drafts, `ahub intake` (#511 AC1 CLI, AC2 to AC4) | on after release; person-only except `approve`, which the configured conductor may run too (#933); a draft is held until `ahub intake approve`, so nothing changes for work that does not use it; the dashboard Plan sheet stages the same held drafts and refuses delegated live-test intake (#1144) | drafts opened, approved and discarded in `ahub backlog list` and the board history (`draft approved`, `intake unsplit` with its reason); the share of drafts the planner or hub model split without a reason on file |
|
|
104
105
|
| Machine-local schedules (#512 AC1, AC3) | on after release for a person who adds `schedules` to `config.local.json` (`every` `<n>m\|h\|d`, 15 minute minimum); nothing runs without it, and a committed config cannot set it | `ahub status` shows one `schedule <id>` line (next run, last run, task, skipped runs); the backlog cards the hub proposed; no second card while the first is open |
|
|
105
106
|
| Calendar-anchored schedules, `cron` and `tz` (#1017) | on after release for a person who writes `cron` (five fields) with an optional `tz` in `schedules`; `every` is unchanged and a project without `cron` sees no change | `ahub schedule list` and `ahub status` show the expression and the next run in the schedule's zone; one task per fire, not one per missed fire after downtime; a skipped or repeated local time on a change day runs once; a too-frequent expression refused at load with the entry named |
|
|
106
107
|
| Schedule commands and dashboard next run, `ahub schedule list\|run\|pause\|resume` (#512 AC4, AC3 UI) | on after release for a person who configured `schedules`; `run`, `pause` and `resume` are the person's or the configured conductor's (#933), nothing changes for a project with none; the dashboard table is read-only | `ahub schedule list` rows and the dashboard Schedules table (state, next run, last run, task); `paused` and manual runs in the board history of the task a run makes; a pause that is never replayed as a run on resume |
|
|
@@ -139,7 +140,9 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
139
140
|
| Peer terminals open in the target project's Orca worktree (#1089) | on wherever a TUI start opens a terminal through Orca; fixture coverage only (a fake `orca` CLI answers `worktree list` and records every call: a start from another project's terminal, refusals for no match, a parent or child root, an archived entry, two matches, a cut-off list and an Orca failure). Run against a real second project in Orca is unverified and not run here (no live panes) | hub.log lines `the hub opened no watch pane (Orca has no worktree whose root is this project's root ...)` and `ahub start` refusals that name the same cause, and no `ahub <peer>` failing its project-root readback after a hub-made start |
|
|
140
141
|
| Crash-recovery notices that clear (#1082) | on after release and upgrade, for the first crash a hub recovers from after that; fixture coverage only (`test/crash-notices.test.ts`: a real daemon over a planted crashed run, peers attached through the bus, rows resolved through the control path). A real `kill -9` recovery on a project with live peers is not recorded here | the `crash` lines of `ahub status --json` after every peer is attached and the held rows are resolved (expected: the headline only); the headline count against `ahub queue list` for the crash's own rows; any `run ahub ... again` line still showing next to an attached peer |
|
|
141
142
|
| Urgent accept takes back unaccepted offers; WIP refusal splits accepted from offered (#1080) | on after release and upgrade; fixture coverage only (`test/urgent-wip.test.ts`: a real `Tasks` over a real board, an owner at its limit with one accepted task and offers). A live urgent task for a busy owner is not recorded here | task history: `unassigned` by `hub` with a `displaced by urgent task` note; the planner notice `was taken back from`; any `planner WIP capacity` refusal that still reads as one undivided list of open tasks |
|
|
142
|
-
| Declared needs keep work from a peer that cannot do it (#1081: `needs_network`, `needs_worktree`) | on after release and upgrade, for tasks proposed with `needs_network` or `needs_worktree` (or `--needs-network`, `--needs-worktree`); fixture coverage only (`test/routing-network-needs.test.ts` and `test/routing-worktree-needs.test.ts`: routing, `route explain`, explicit assignment, a reservation, accept with a rostered fake Pi and Codex, and a real git repo showing a refused accept creates no branch ref; `test/capabilities-network-worktree.test.ts`: a real daemon's per-peer capabilities). A real Pi or local worker offered flagged work is not recorded here
|
|
143
|
+
| Declared needs keep work from a peer that cannot do it (#1081: `needs_network`, `needs_worktree`) | on after release and upgrade, for tasks proposed with `needs_network` or `needs_worktree` (or `--needs-network`, `--needs-worktree`); fixture coverage only (`test/routing-network-needs.test.ts` and `test/routing-worktree-needs.test.ts`: routing, `route explain`, explicit assignment, a reservation, accept with a rostered fake Pi and Codex, and a real git repo showing a refused accept creates no branch ref; `test/capabilities-network-worktree.test.ts`: a real daemon's per-peer capabilities). A real Pi or local worker offered flagged work is not recorded here. A hub-made worktree for a sandboxed peer (#1115) is covered by fixtures only (`test/task-worktree.test.ts`: real git, a bare origin, the hub's commit and push, a moved branch or HEAD refused, the path policy, decline and cancel cleanup; `test/task-worktree-sandbox.test.ts`: the real `sandbox-exec` profile, unchanged, with the peer editing and the hub's commit after (the peer's own commit failing is asserted in `test/sandbox-git-refs.test.ts`, #1123); `test/task-worktree-tasks.test.ts`: accept, refusal, decline, cancel and the done hand-off through `Tasks`), so it is on after release and upgrade, for flagged work offered to Pi or local in a git repository with a GitHub origin, and its metric is a Pi or local task whose branch was committed and pushed by the hub and reviewed, with no `.git` write attempt from the sandbox (expected: none) and no empty `task/*` refs left by a declined or cancelled one | `ahub route explain` lines `skipped, no network` and `skipped, no worktree` for Pi or local; Pi or local declines of work that needed the network or a worktree (expected: none once the task is flagged); empty branch refs left by a declined Pi or local task (expected: none for flagged tasks); unflagged tasks that were declined for a missing worktree or registry, which show the planner is not flagging them |
|
|
144
|
+
| Sandbox refuses `.git` ref, HEAD and worktree writes (#1123) | on after release and upgrade for the local worker and Pi (hub sandbox); fixture coverage under the real `sandbox-exec` only (`test/sandbox-git-refs.test.ts`: the main checkout, a hub-made worktree, a worktree beside its project, a bare repository's worktree, a submodule, a nested one and a linked worktree's, folded names, projects below directories named like the rules; `test/sandbox.test.ts` and `test/tools.test.ts` rewritten where they asserted a sandboxed commit). It needs macOS, so the Linux gate skips it. A real Pi or local worker task is not recorded here; since #1129 a sandboxed task of a write class gets the hub's worktree and commit whether or not it is flagged | a Pi or local write-class task that ends with uncommitted edits in the main checkout (expected: none, the hub made it a worktree), the local `git` tool's `the sandbox does not let you move a branch` note in turn results, and any `Operation not permitted` on a `.git/refs`, `HEAD` or `worktrees` path from a command that should not need it |
|
|
145
|
+
| Hub worktree and commit for every write-class task of a hub-sandboxed owner (#1129) | on after release and upgrade, for `implement` and `bulk_edit` work offered to Pi or the local worker in a git repository, whether or not the task says `needs_worktree`; fixture coverage only (`test/task-worktree-tasks.test.ts`: an unflagged implement and bulk_edit task get the worktree at accept, the hub commits it at `hub_task_done`, decline and cancel clear it, read-only classes and PII tasks get none, a self-claim makes it; `test/routing-worktree-needs.test.ts`: write-class work is not offered where the hub cannot make a worktree and the trace names the cause, read-only classes are not refused; `test/pi-daemon.test.ts` runs a real Pi accept in a repository). A real Pi or local worker task through a whole accept, edit and done is not recorded here | write-class tasks owned by Pi or local whose `hub_task_done` carries a hub commit and branch (expected: all of them); `ahub route explain` lines `skipped, no worktree` for Pi or local on write-class work outside a git repository (expected there, with the cause), write-class tasks that stay with Claude or Codex because the hub could not make a worktree (the cost of this rule: watch whether it starves Pi), and empty `task/*` refs left by a declined or cancelled one (expected: none) |
|
|
143
146
|
| Paged `hub_task_list` (#1083) | on after release and upgrade, for agents (an agent session's `ahub board` follows the pages); the person's console and `ahub board` from a terminal keep the bare array. Fixture coverage only (`test/task-list-page.test.ts`: a real daemon with 600 seeded tasks; `test/board-agent-paged.test.ts`: the real `ahub board` and `--columns` under an agent identity over a two-page board). A real conductor session reading the live board is not recorded here | the size of a conductor's `hub_task_list` result on the live board (expected: under 64 KB, a `next` cursor while more exist); a page walk that ends with no task repeated; `ahub board` run from an agent shell listing as many tasks as `ahub board` from a terminal; any peer or script that still fails parsing `hub_task_list` as a bare array |
|
|
144
147
|
| `ahub init` guided prompt (#1065 T2) | on wherever a person runs `ahub init` at a terminal on a new project with no flag and no `--yes`; fixture coverage only (the real CLI under a scripted pty in a temporary HOME: `test/init-prompt.test.ts`). A person answering it on a real new project is not yet recorded and not run here | `ahub init` runs by a person that end with `wrote ...` after the plan, against runs that end `nothing was written` (N, Ctrl-C, Ctrl-D, three bad answers); no `Write this?` line in any log of a peer, live-test or piped run; the settings a person changes from the default, per question |
|
|
145
148
|
| `ahub init` settings flags (#1065 T1) | on wherever a person runs `ahub init`, new or existing project; fixture coverage only (the real CLI against scratch projects and a scratch hub home). The guided prompt (T2) and the specs rows (T3) are not built, and a person using the flags on a real project is not yet recorded | each `--dry-run --json` `settings` row is a change a person asked for (key, file, old and new value), `ahub init` refusals name the allowed values, and `git diff` of `.agenthub/config.json` after an init with flags shows only the named keys |
|
|
@@ -151,6 +154,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
151
154
|
| --- | --- | --- |
|
|
152
155
|
| `ahub init --specs/--no-specs/--spec-review` and person-only `ahub specs stamp` (#1064 T3) | on after release: a new or existing project gets the specs block by default; no repository design specs or stamps are recorded with it here yet; fixture coverage only (real CLI against scratch repositories: `test/init-specs.test.ts`, `test/specs-stamp.test.ts`, `test/check-docs-parity.test.ts`). A person stamping a real spec in a terminal is unverified and not run here (no live terminal session) | `ahub init --dry-run --json` `settings` rows for `specs.enabled` and `specs.review`; the specs block present in `AGENTS.md` of projects where `specs.enabled` is true and absent where it is false; `specs stamp` runs that end with `stamped N documents` against refusals for uncommitted covered paths; no `verified-against` change authored by an agent (`git log -p` on spec files) |
|
|
153
156
|
| Per-call write outcomes (#1078) | source/fixture coverage; installed-hub activation and the reported live 35-45 s stall remain unverified | `test/tool-request.test.ts`, `test/control-client.test.ts` and real daemon/channel fixtures count one effect per request ID, preserve pending joins and reject changed scope/payload; the 600-task synthetic p95 receipt is `docs/verification/2026-11-02-control-write-outcomes.md` |
|
|
157
|
+
| Control-write timing and event-loop delay (#1126) | source and isolated fixture coverage; live activation and cause of the reported stall remain unverified | `test/control-write-trace.test.ts` pins metadata/privacy/caps, lazy screens, five-minute diagnostic expiry and completed-span correlation; `test/control-write-telemetry.test.ts` checks admission before scanning, forces a blocked real daemon write and checks phase logs/status counters; historical UTC windows are in `docs/verification/2026-11-03-control-write-stall-windows.md` |
|
|
154
158
|
| Recipient settlement and inbox reads behind held rows (#1079) | source/fixture coverage; installed-hub activation and a live busy-peer settlement remain unverified | `test/recipient-settlement.test.ts` checks busy own-row completed/discard with reason and revision, foreign-row refusal and queued reads behind an unchanged held row; pause/recovery/lifecycle fences remain covered |
|
|
155
159
|
| Design spec inspection and task notices (#1064 T1/T2) | source/fixture coverage only; no repository design specs configured yet; dogfood drafts follow in later phases | `test/specs.test.ts` checks graph/freshness and empty-project silence; `test/specs-tasks.test.ts` checks report/require, head-bound acknowledgements and privacy; committed-head inspection fixtures exclude dirty/main-checkout bypasses; adoption metrics are the counts of `spec not updated` reports, acknowledged reasons and unchanged-spec refusals |
|
|
156
160
|
| Screened room chat and person inbox (#446 X4/X5/X5b) | default off here; requires person enrollment/exposure; console panel 8 and dashboard Agents remain metadata-only; person CLI alone can show one inbox body; real two-machine/account leg remains unverified | signed completed (admitted) versus immutable completed (inbox); once-only inbound count, body-free metadata/list JSON, framed/control-stripped person show, done/discard/expiry purge and fixed stored-byte cap/age refusals, post-ack retries; 1,100-row complete-list ceiling; no broadcast/roles/board/body telemetry, key/storage creation from status or mixed-version success claim; existing restart/binding/disposition regressions |
|
|
@@ -177,6 +181,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
177
181
|
| Verdict mirror (#786 T3) | `auto_merge = "dry-run"` first (same setting as the guarded merge): the dry-run notice names the one comment review it would post; `on` after one dry-run notice matches a verdict | one `agent-hub verdict:` comment review per (task, head, verdict) on each PR; none at a stale head; the headline alone for a private task |
|
|
178
182
|
| Guarded merge and result recording (#786 T1/T2, #899) | `auto_merge = "dry-run"` first in this repository's `.agenthub/sdlc.toml`; `on` after one dry-run report matches a manual merge; the report prints for a person by default and as a document with `--json` | `ahub sdlc merge <task> --dry-run` reports the mode, the decision, each refusing gate and the `gh` command it would run, readable without `--json`; `--json` is byte for byte the view printed before #899 (`test/sdlc-output.test.ts`); merges the hub made against merges a person or reviewer made by hand; host merge/cleanup records and owner-notice status; fake-gh ordering/idempotency proof, no live cleanup claim |
|
|
179
183
|
| Peer `DOING` column (#878) | on after the release for Claude sessions started with `ahub claude` and the Codex TUI; ACP peers show it only when their agent sends a plan | `ahub status` shows a title or current item for an active Claude and Codex peer without a hub tool call; `[private]` during PII work; the column disappears when no peer has a value |
|
|
184
|
+
| Pi/local session titles (#1055) | available after release for hub-owned Pi/local sessions; native Pi setter/readback is probed, installed use and the live restart receipt remain unverified (#1143) | first `hub_set_title` succeeds once, later agent writes return `already_named`, and person rename replaces it; live status shows the title or a screened unnamed label while `status.json` omits both |
|
|
180
185
|
| Console and dashboard | on; #719 pending-history reads and bounded native launch retries take effect after release | control-request latency, connection timeouts and launch retry notices; daemon CPU/RSS samples, measured separately from lifetime CPU |
|
|
181
186
|
| Usage view (#683) | CLI (`ahub usage`, U2), console Usage tab `7` (U3) and dashboard Usage view (U4) shipped | its own panels |
|
|
182
187
|
| Kimi usage from its wire log (#285 phase 2) | on after the release when `budget.kimi_tokens_5h` is set; this repository sets it | `tokens` and `usage` (`kimi_wire`) events per Kimi turn, the `tokens` window in `ahub budget`, and the count of `kimi usage unknown` notices; the live check against Kimi's `/usage` (AC11) stays opens |
|
|
@@ -185,6 +190,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
185
190
|
| Settings reload | on | reloads applied, pending restarts |
|
|
186
191
|
| Config editing from the console and dashboard (#689) | on after release; `ahub settings edit` and console key `c` run here, the dashboard Structure group needs `ahub ui --settings`; executable keys stay console only | `config_edit` events (edits applied by tier and source), refusals shown with the loader reason, restarts left pending |
|
|
187
192
|
| Upgrade and recovery | on, per release | upgrade receipts in `docs/verification/` |
|
|
193
|
+
| Office planning view (#264 phase 5) | source/fixture implementation; available after release when the person selects Flat or Isometric (Off by default); the live two-agent, both-theme AC9 browser look remains unverified | `test/office-model.test.ts` pins Backlog count/order/cap, reserved/pin/waits and release/planner metadata; `test/office-view.test.ts` pins dock and overflow navigation, keyboard access, stable wall-to-To do card nodes, geometry, reduced motion and light/dark token contrast; served-page raw/gzip deltas are measured against the PR merge base |
|
|
188
194
|
| acon console plugin (#935) | off here until a person runs `ahub setup` after the release and `acon ui` on this machine; the plugin registers per agenthub home, not per repository | `acon plugins` shows `ahub verified`; the console's agent-hub panel shows this repository's live board, and an approval answered from the console inbox appears in hub.log as `answered option allow_once by dashboard`. Space (#1012): adopted with the plugin, no separate switch; acon's Space view (Flat, Room, 3D) shows this repository's peers as actors (state and marks matching the dashboard's office), the board columns as queue/work/review/done zones with the same counts, and overlap links plus message arcs (broadcasts to every other desk) as links; clicking an actor or card opens this project's agents or board panel |
|
|
189
195
|
| Agent CLI version policy and trust (#691) | on after the release: Codex 0.163.0 verified by the [2026-10-22 receipt](verification/2026-10-22-codex-reviewer-isolation.md) and 0.164.0 by the [2026-10-24 receipt](verification/2026-10-24-codex-0164-reviewer-isolation.md); Kimi 2.3.0 and Qwen 0.26.0 verified by the [model-free receipt](verification/2026-10-22-kimi-qwen-compat.md), Kimi 2.3.1 by the [2026-10-25 model-free receipt](verification/2026-10-25-kimi-231-reviewer-compat.md) and 2.3.2 by the [2026-10-26 one](verification/2026-10-26-kimi-232-reviewer-compat.md), with account/provider live legs unverified; agy 1.4.4 in-line | model-free isolation receipts, `ahub agents` verdicts, versions trusted per machine, lead time from an `agent-compat` issue to a receipt |
|
|
190
196
|
| Peer child environment isolation (#1077) | source and fixture coverage; no native account or Orca session used | daemon peer children, version probes and process-table helpers contain no `ORCA_*`; person-owned native launches keep their fixture pane's `ORCA_*` context while replacing agent identity; explicit Claude/Codex selectors pass through where the adapter inherits them; preload clears ambient selectors without changing fixture home bytes |
|
|
@@ -205,7 +211,7 @@ Run `ahub report --dogfood --since 7d --json` against this repository's own hub
|
|
|
205
211
|
- `null` in JSON means unknown; the text format prints `unknown`. Source availability and completeness are separate. Partial event data is an observed subset, not a complete token bill; event, usage and attribution coverage are separate.
|
|
206
212
|
- Flow is scoped to at most 16 merged PRs found by a capped GitHub read. PR lead time runs from the earliest linked task proposal to the last linked task approval. Missing task links remain unknown. Review rounds reuse `costMetrics`' board handoff definition. CI reads use `head_sha=<recorded-head>&created=<since>..<until>` so unrelated weekly or lifetime runs cannot consume a PR's 100-run page. Only a fully enumerated commit/review/head SHA set is used, including when REST omits PR associations. At most eight heads per PR and 32 CI requests across the 16 selected PRs run under the shared 20 s deadline and 128 KiB response cap. Missing/truncated metadata, a failed or truncated head response, duplicate run ids, more than 100 combined PR runs or an exceeded request/deadline budget keeps that PR's CI unknown. Recent merged PRs are read first. First-pass CI needs the first run's original conclusion and a PR opened within the window; older or unknown PR opening times stay unknown because earlier runs may be outside the window. A later rerun's success does not certify the first result. Same-head reruns count actual `run_attempt - 1`, not duplicate workflows.
|
|
207
213
|
- Connector counts are review threads first opened by that bot after all linked tasks were approved, not a severity classification. Bug counts use explicit cross-references and the `bug` label; they show association, not proven causality, and include the observation age up to 14 days.
|
|
208
|
-
- Each input event/log file has a 16 MiB read cap. The board
|
|
214
|
+
- Each input event/log file has a 16 MiB read cap. The board is read in two bounded parts (#1147). The PII inventory is read completely from the whole board, ids and PR refs only, with no text, under a 2000-task cap and independent of the window; a task whose signals or receipt cannot be read, or an overflow of that cap, makes it incomplete and forbids every per-PR GitHub read. The other task rows are limited to tasks overlapping `[since, until]` (updated at or after `since`, created at or before `until`), at most 500 rows, with per-cell and total byte bounds; their overflow marks the board source incomplete but no longer blocks the PR reads. Every task linked to a PR merged in the window is also read, whatever its update time, under the same 500-row bound, so a PR's lead time, review rounds and findings never come from a partial sibling set; if that read overflows, the source is incomplete and those PR metrics are unknown. GitHub has a 20 s deadline, a 16-PR cap, 100-node pages and 128 KiB responses. Missing, malformed or truncated evidence remains incomplete; the report does not silently call it zero.
|
|
209
215
|
- Digest and held counts describe retained journal rows created in the window. The journal prunes terminal rows, so these are not historical totals. It does not record the first delivery timestamp: `updatedAt` must not be used as delivery latency.
|
|
210
216
|
- Control latency, connection timeouts, CPU/RSS history, actual snapshot exhaustion totals and the adjudicated real-blocker rate currently have no durable source and remain unknown. Snapshot budget notices count one log diagnostic per affected burst. Error classes and advise-gate matches are fixed-pattern log counts; no raw line is exported.
|
|
211
217
|
- Adoption row ids are the 1-based table-row order in this document at the feature-table source commit recorded in the receipt. A matching event is evidence of that leg's use, not proof that the entire feature was enabled or correct. Rows without a dedicated observable leg stay unknown.
|
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.30.0 and control protocols 16 through 17. 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
|
|
@@ -278,6 +278,42 @@ dashboard's peer rows and the conductor's `hub_status` show the same value; it
|
|
|
278
278
|
lives in the daemon's memory only, never in `status.json`, a log, an event or
|
|
279
279
|
memory capture. Board WIP is unchanged.
|
|
280
280
|
|
|
281
|
+
Pi and the local worker can name an unnamed session with `hub_set_title`
|
|
282
|
+
(#1055). A normalized title is 1-80 characters; the first agent name is final.
|
|
283
|
+
The person replaces it with `ahub title <peer> <text...>`, or selects the peer
|
|
284
|
+
in the console and presses `t`. The rename input starts empty after the command
|
|
285
|
+
prefix, even when an unnamed label is visible. Other peers rename in their
|
|
286
|
+
native UI. No helper model is called, and task, branch and instance names are
|
|
287
|
+
independent. A private turn, an open PII owner/reviewer assignment, a sensitive
|
|
288
|
+
title or a failed metadata screen refuses the write.
|
|
289
|
+
|
|
290
|
+
Every refused title call includes its reason code plus a public cause and next
|
|
291
|
+
step. An unconfirmed write can have landed: check `ahub status` before retrying
|
|
292
|
+
when the error says it may have been applied. A person rename on an idle Pi
|
|
293
|
+
session that has never exchanged a message creates native title metadata but
|
|
294
|
+
may not create a session file yet. Recovery preserves that state by refusing
|
|
295
|
+
ID-only recreation; exchange one message or explicitly start a new session,
|
|
296
|
+
then retry recovery.
|
|
297
|
+
|
|
298
|
+
An unnamed session displays a muted label from the first acknowledged hub
|
|
299
|
+
delivery, at most 60 normalized characters. Queued or unaccepted messages do not
|
|
300
|
+
supply it. The console and configured conductor can see this incoming-message
|
|
301
|
+
label; other agent status readers see `unnamed`. Its source note distinguishes
|
|
302
|
+
the incoming message from text written by the recipient peer. The label is
|
|
303
|
+
computed only for live status and dashboard reads;
|
|
304
|
+
`status.json`, events, logs and memory receive no derived label. The daemon
|
|
305
|
+
stores only the peer's title-session ID and acknowledged delivery/envelope IDs
|
|
306
|
+
for native-session peers in `session-title-inputs.json`. The
|
|
307
|
+
[storage contract](design/adapters.md#session-title-slots) defines its bounds
|
|
308
|
+
and lifetime. Removed instances are pruned when their removal applies, and
|
|
309
|
+
Local bindings are discarded because the worker starts a new memory session.
|
|
310
|
+
After restart it recomputes the label only when
|
|
311
|
+
the same session and retained journal original match; a new session or pruned
|
|
312
|
+
original shows no inherited label. Pi's real name stays in Pi's native session;
|
|
313
|
+
the local worker's name lives only with that worker's in-memory session. The
|
|
314
|
+
native setter/readback probe is separate from the still-pending live restart
|
|
315
|
+
receipt tracked in #1143 and `docs/smoke.md`.
|
|
316
|
+
|
|
281
317
|
In Peers, select a row and press `w` to edit `tasks.wip_limits.<peer>`, prefilled
|
|
282
318
|
with its current limit. The editor stays on Peers and uses the existing Settings
|
|
283
319
|
value, daemon preview, nonempty reason and `y` confirmation flow; Esc cancels without writing. The
|
|
@@ -453,7 +489,7 @@ OS color preference through CSS. Both inline scripts and the style retain CSP
|
|
|
453
489
|
hashes; there are no external chart/theme assets. Live theme/readability inspection
|
|
454
490
|
is tracked in `docs/smoke.md` and remains unverified until performed.
|
|
455
491
|
|
|
456
|
-
The dashboard Office section (#264, phase 1
|
|
492
|
+
The dashboard Office section (#264, phase 1) draws the same snapshot as a
|
|
457
493
|
static flat office: one desk per peer in a stable slot (claude, codex, kimi, pi,
|
|
458
494
|
local, then others by id; a peer going offline dims its desk and never moves
|
|
459
495
|
another), rooms for the board columns in a fixed order (To do, Work floor,
|
|
@@ -480,6 +516,16 @@ projection without animating; the settle rule and reduced motion apply
|
|
|
480
516
|
unchanged. The live browser look is tracked in `docs/smoke.md` and
|
|
481
517
|
remains unverified until performed.
|
|
482
518
|
|
|
519
|
+
Phase 5 (#1152) adds a Backlog room before To do: cards in rank, then
|
|
520
|
+
priority, then id order, at most 8 with "+N more" opening the backlog filter,
|
|
521
|
+
each with its reserved, pinned and waiting marks, and a count equal to the
|
|
522
|
+
board's backlog count. Up to three release docks (planning, active or frozen
|
|
523
|
+
releases, then "+N releases") show approved/scope and the cut date; activating
|
|
524
|
+
a dock sets the task list's release filter. Each planner-role desk carries the
|
|
525
|
+
number of unplanned backlog cards (no rank, no reservation), and the wall shows
|
|
526
|
+
that count when no planner desk is visible. All of it is read from the existing
|
|
527
|
+
snapshot; the design is `docs/specs/2026-10-12-office-view-design.md`.
|
|
528
|
+
|
|
483
529
|
Motion (phase 2): card moves between rooms and desks, message arcs between
|
|
484
530
|
desks (from the hub or the console they start at an anchor point), delivery
|
|
485
531
|
warning marks and the busy latch all follow the snapshot. Motion is CSS only:
|
|
@@ -713,8 +759,8 @@ setting (`ahub settings set peers.pi.start_mode headless`), asks for the
|
|
|
713
759
|
background peer instead. The project uses its existing OmniRoute connection for DGX;
|
|
714
760
|
`pi.dgx_coding` and `pi.dgx_fast` select the gateway's configured model IDs.
|
|
715
761
|
Every Pi start (headless, TUI, console or auto start) first runs the configured
|
|
716
|
-
`pi.cmd` with `--version` (#847). Pi 1.4.0
|
|
717
|
-
([model-free receipt](verification/2026-10-26-pi-140-compat.md)); another
|
|
762
|
+
`pi.cmd` with `--version` (#847). Pi 1.4.0 and 1.5.0 are verified
|
|
763
|
+
([1.4.0 model-free receipt](verification/2026-10-26-pi-140-compat.md), [1.5.0](verification/2026-11-03-pi-150-compat.md)); another
|
|
718
764
|
version, or one that cannot be read, is refused before Pi starts, unless the
|
|
719
765
|
person trusts that exact version with `ahub agents trust pi <version>`.
|
|
720
766
|
|
|
@@ -1097,15 +1143,23 @@ routing, a reservation, `ahub task assign` and `hub_task_accept` all refuse it b
|
|
|
1097
1143
|
A hub-sandboxed peer (Pi, the local worker) has none while `local.bash_network` is off: `no network: local.bash_network
|
|
1098
1144
|
is off ...`.
|
|
1099
1145
|
- `needs_worktree` is for work that must run in its own git worktree on a task branch (the repository rule). A
|
|
1100
|
-
hub-sandboxed peer cannot
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
the hub
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1146
|
+
hub-sandboxed peer cannot run `git worktree add`, because it writes under the git common directory and runs outside
|
|
1147
|
+
the sandbox by design (#270), so since #1115 the hub makes the worktree for it at `.worktrees/<peer>-<task>` on the
|
|
1148
|
+
branch `task/<task>-<peer>`, before the accept write. The peer edits files there and does not run git; at
|
|
1149
|
+
`hub_task_done` the hub stages, commits and pushes the branch. The capability is true only where the hub can make
|
|
1150
|
+
the worktree. Otherwise it is false and the refusal says why and what to do: `no worktree: the hub cannot make a task
|
|
1151
|
+
worktree for it: the project is not a git repository; run git init there, ...`. A refused accept creates nothing,
|
|
1152
|
+
so no empty branch ref is left behind (the Pi accepts of #621 and #565 left two). Declining or cancelling removes
|
|
1153
|
+
the worktree and its empty branch; one with uncommitted changes is kept and reported. The sandbox profile is not
|
|
1154
|
+
changed (docs/security.md, "Hub-made task worktree").
|
|
1155
|
+
|
|
1156
|
+
A peer whose capability the hub cannot tell is never refused on this ground. Work that declares no need is routed as
|
|
1157
|
+
before, with one exception (#1129): write-class work (`implement`, `bulk_edit`) is treated as needing a worktree
|
|
1158
|
+
whether or not it is flagged, because a hub-sandboxed owner cannot commit (#1123) and the hub commits in its worktree.
|
|
1159
|
+
Such work is never offered to a hub-sandboxed peer on a project where the hub cannot make a worktree, and
|
|
1160
|
+
`ahub route explain` says `no worktree` and the cause; `test`, `summarize`, `triage`, `review` and `plan` get none,
|
|
1161
|
+
and neither does a PII task. The other flags are a person's or a planner's statement about the work, so an unflagged
|
|
1162
|
+
task can still reach a peer that cannot meet them.
|
|
1109
1163
|
|
|
1110
1164
|
Network is off unless `local.bash_network` says otherwise. With `true` it goes
|
|
1111
1165
|
only through the hub's egress proxy on a loopback port (0.11): commands get
|
|
@@ -1245,6 +1299,60 @@ its delivery ID and generation; it has no request key argument.
|
|
|
1245
1299
|
The latency receipt and its synthetic-only scope are in
|
|
1246
1300
|
[control-write verification](verification/2026-11-02-control-write-outcomes.md).
|
|
1247
1301
|
|
|
1302
|
+
|
|
1303
|
+
## Control write timing and loop delay (#1126)
|
|
1304
|
+
|
|
1305
|
+
After upgrading to a release containing #1126 and restarting through the normal
|
|
1306
|
+
upgrade workflow, `ahub status --full` shows aggregate control-write timing
|
|
1307
|
+
counters. An older hub omits them. They are process-local diagnostics, reset at
|
|
1308
|
+
restart, not durable success receipts or a count of unique business effects.
|
|
1309
|
+
This feature does not change a request timeout or make a retry safe.
|
|
1310
|
+
|
|
1311
|
+
A slow tracked operation (at least 1,000 ms on a monotonic clock) writes a
|
|
1312
|
+
`control_write_slow` JSON record to hub.log. The record contains a closed request
|
|
1313
|
+
kind, an optional public task number, elapsed time, outcome and phase durations.
|
|
1314
|
+
`returned`/`threw` describes the handler, not business success or whether a write applied.
|
|
1315
|
+
Client-side timing is opt-in with `AHUB_CONTROL_WRITE_TIMING=1` in the client or
|
|
1316
|
+
MCP server environment. Its slow records go to stderr, never stdout, and omit task
|
|
1317
|
+
numbers because the client has no authoritative privacy view. No request/rid,
|
|
1318
|
+
actor/session identifier, path, task text, argument, external output or error
|
|
1319
|
+
message enters a timing record. Host privacy is checked again before logging.
|
|
1320
|
+
An unresolved task identity (including a noncanonical string id) suppresses daemon
|
|
1321
|
+
diagnostics while the operation keeps its normal validation and behavior.
|
|
1322
|
+
|
|
1323
|
+
The daemon samples its event loop every 100 ms. A missed tick delayed by at least
|
|
1324
|
+
250 ms can write `control_write_loop_delay`, including bounded observed spans.
|
|
1325
|
+
Recently completed synchronous intervals are retained so a span that blocked the
|
|
1326
|
+
loop can be identified after its callback has returned. An open asynchronous span
|
|
1327
|
+
is only a concurrent wait, not proof that it occupied the CPU; untracked occupancy
|
|
1328
|
+
is reported as unknown. Background snapshot, queue/status and memory boundaries
|
|
1329
|
+
use the fixed `background` kind rather than inventing a tool request.
|
|
1330
|
+
|
|
1331
|
+
Per observer, retained work is capped at 128 operations, 256 active span registrations, 512
|
|
1332
|
+
recent intervals and 8 emitted phase/span items. Phase totals use only the closed
|
|
1333
|
+
phase set; a full active-registration map never discards a finished phase or recent
|
|
1334
|
+
synchronous interval. There is no per-request cutoff that can hide a late block.
|
|
1335
|
+
The slow and loop categories each allow at most one line per second, with a shared
|
|
1336
|
+
60-line/minute ceiling; each JSON record is at most 2,048 UTF-8 bytes. Dropped work
|
|
1337
|
+
and logs are counted. Normal ring rotation and settle-time cleanup are excluded
|
|
1338
|
+
from the full-status dropped total. A stopped probe cannot be started again. Nested durations are not additive. Status counters include
|
|
1339
|
+
background observations and do not identify a blocking cause on their own.
|
|
1340
|
+
|
|
1341
|
+
Unanswered diagnostic requests expire after five monotonic minutes, reclaiming
|
|
1342
|
+
their operation and span slots without cancelling the underlying work or changing
|
|
1343
|
+
its eventual result. Full status lists `expired` separately from capacity/log drops
|
|
1344
|
+
and normal ring rotation. Argument screening starts only after socket admission;
|
|
1345
|
+
model-input diagnostic screens run once only when tracing can admit the observation.
|
|
1346
|
+
|
|
1347
|
+
Board-write, queue/status, memory and external-call phases locate an observed
|
|
1348
|
+
boundary; they do not weaken its existing authority, privacy or execution gates.
|
|
1349
|
+
The probe is unref'd and stopped at daemon shutdown or failed startup. The
|
|
1350
|
+
[historical window correlation](verification/2026-11-03-control-write-stall-windows.md)
|
|
1351
|
+
separates one 60-second all-event gap from review waits with continuing periodic
|
|
1352
|
+
callbacks. The instrumentation is intended to diagnose the next naturally
|
|
1353
|
+
occurring stall; it has not been run against the live daemon by that task.
|
|
1354
|
+
|
|
1355
|
+
|
|
1248
1356
|
## A two-agent task and review
|
|
1249
1357
|
|
|
1250
1358
|
Choose an owner explicitly, then inspect the reviewer selected by the project
|
|
@@ -1702,7 +1810,7 @@ ahub memory forget 1a2b3c4d # a person's; also promote, demote, sup
|
|
|
1702
1810
|
|
|
1703
1811
|
`"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
|
|
1704
1812
|
|
|
1705
|
-
The exact-pinned `@staix/agent-mem` 0.
|
|
1813
|
+
The exact-pinned `@staix/agent-mem` 0.20.1 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.
|
|
1706
1814
|
|
|
1707
1815
|
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).
|
|
1708
1816
|
|
|
@@ -2179,7 +2287,7 @@ Run `ahub autonomy on` from a person's terminal. It previews the concrete settin
|
|
|
2179
2287
|
|
|
2180
2288
|
On a running hub, the on confirmation retains peer-specific consent under the machine hub home, outside the project and its execution roots, authenticated and bound to this project and the exact per-peer permission-mode values the person confirmed. A project-file marker or a forged state row cannot confirm never-ask. Missing or changed evidence keeps the ordinary per-peer console confirmation; changing one peer's mode invalidates that peer's consent. Start defaults and action-policy changes do not invalidate mode consent. Off and preset undo remove retained consent, so restoring a never-ask value with undo needs a new on confirmation, or a hub start under a trusted machine opt-in when the value exactly matches the preset plan, to retain it again. An agent shell, a delegated live-test command, a tools connection and the conductor cannot turn autonomy on or off. No hub tool exposes it.
|
|
2181
2289
|
|
|
2182
|
-
`ahub autonomy status`
|
|
2290
|
+
`ahub autonomy status` starts with a padded peer table of current effective modes and preset next-start defaults (`unmanaged` when no mode is requested). Guarded actions follow, grouped by identical class, verdict and reason, with the affected peers (or "all peers") and counts of classes and classes enforced for at least one peer. Shared unknowns are printed once with their peer lists; floor-shaped missing entries are not repeated. Machine-default and Claude-home notices are retained, and paths under the user's home appear with `~`. Reasons and unknowns keep their original text. `--json` returns the unchanged structured report; an older hub without structured peers keeps the legacy line output. Plugin, native policy, terminal provider and GitHub branch protection are reported as missing or unknown when no current evidence establishes them. Orca uses the existing registered worktree opener; a custom `terminal.open` template is preserved. A headless or CI invocation selects headless defaults where the kind supports them. With the hub stopped, status reads only the project configuration: effective modes and retained consent are reported unknown, and every floor class is not enforced.
|
|
2183
2291
|
|
|
2184
2292
|
A controlled restart or upgrade checks target feature `project_autonomy` while preset metadata or retained consent is active. A target without it is refused before the source is held or stopped; it could not read the new config metadata. Turn the preset off before selecting such a target.
|
|
2185
2293
|
|
|
@@ -2324,6 +2432,7 @@ A guarded file edit that the daemon keeps at its accepted value remains visible
|
|
|
2324
2432
|
| Routing | `routing.stay_switch`, `routing.classes.<class>.peers`, `.escalate_to`, `.route`, `.pi_backend` | `routing.local.toml` | at once |
|
|
2325
2433
|
| Switches | `research.enabled`, `approvals.notify`, `snapshots.enabled` | `config.local.json` | live, without disturbing an active turn |
|
|
2326
2434
|
| Switches | `coordination` | `config.local.json` | newly created tasks only |
|
|
2435
|
+
| Switches | `worktrees.quiet_days` (0-3650, default 7, 0 never shelves by quiet time), `worktrees.alert_over` (0-100000, default 10, 0 never alerts) ([worktree shelf](#the-worktree-shelf-1057)) | `config.local.json` | live |
|
|
2327
2436
|
| 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 |
|
|
2328
2437
|
| Routing | `tasks.wip_limits.<peer>` | `config.local.json` | live |
|
|
2329
2438
|
| 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 |
|
|
@@ -3390,7 +3499,7 @@ version is older than the selected running daemon; it installs nothing.
|
|
|
3390
3499
|
| Runtime | Control protocol window | Legacy status field |
|
|
3391
3500
|
| --- | --- | --- |
|
|
3392
3501
|
| 0.12.20 through 0.25.0 | 16 only | `protocol: 16` |
|
|
3393
|
-
| 0.26.0 through 0.
|
|
3502
|
+
| 0.26.0 through 0.30.0 | 16 through 17 | `protocol: 16`, `protocolMin: 16`, `protocolMax: 17` |
|
|
3394
3503
|
|
|
3395
3504
|
New clients choose the highest common protocol. The runtime supports N-1, so the
|
|
3396
3505
|
published protocol-16 client and channel plugin remain usable; unrelated feature
|
|
@@ -4663,7 +4772,7 @@ selected roster and existing capabilities; the TUI is always a person's start.
|
|
|
4663
4772
|
- 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.
|
|
4664
4773
|
- 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.
|
|
4665
4774
|
|
|
4666
|
-
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)), 0.26.1 ([0.26.1 receipt](verification/2026-10-26-qwen-0261-acp.md))
|
|
4775
|
+
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)), 0.26.1 ([0.26.1 receipt](verification/2026-10-26-qwen-0261-acp.md)) 0.26.4 ([0.26.4 ACP receipt](verification/2026-10-31-qwen-0264-acp.md)) and 0.26.5 ([0.26.5 ACP receipt](verification/2026-11-03-qwen-0265-acp.md)). The separate [0.26.4](verification/2026-10-31-qwen-0264-dual-output.md) and [0.26.5](verification/2026-11-03-qwen-0265-dual-output.md) dual-output attempts did not establish their queued-turn criterion, so `qwen-dual` stays at 0.26.1. A CLI version label alone
|
|
4667
4776
|
is insufficient: startup verifies its native identity/version and advertised mode
|
|
4668
4777
|
ids before any prompt. The earlier local installation reported CLI 0.25.0 while
|
|
4669
4778
|
its package/ACP source said 0.24.1; that was not a ready identity. The 0.26.0 receipt
|
|
@@ -4714,7 +4823,7 @@ Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or
|
|
|
4714
4823
|
|
|
4715
4824
|
## Optional Antigravity (agy) peer
|
|
4716
4825
|
|
|
4717
|
-
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 and 1.4.
|
|
4826
|
+
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, 1.4.7 and 1.4.12 are the verified versions ([1.4.7 receipt](verification/2026-10-26-agy-1.4.7.md), [1.4.12 launcher nonce receipt](verification/2026-11-03-agy-1.4.12-launcher-nonce.md)), any other 1.4.x launches with a stderr warning (agy updates itself; set `AGY_CLI_DISABLE_AUTO_UPDATE=1` for a live run, #1140), 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.
|
|
4718
4827
|
|
|
4719
4828
|
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`.
|
|
4720
4829
|
|
|
@@ -4843,6 +4952,14 @@ A `schedules` entry in `.agenthub/config.local.json` takes either `every` (an in
|
|
|
4843
4952
|
- **Upgrades.** The daemon advertises `calendar_schedules`. While a schedule uses `cron` or `tz`, a restart, upgrade or recovery onto a release without it is refused, naming the reason.
|
|
4844
4953
|
- Out of scope: holiday and exchange calendars. A task whose first step finds a non-working day can end itself.
|
|
4845
4954
|
|
|
4955
|
+
## Registered sources and request drafts (#1144)
|
|
4956
|
+
|
|
4957
|
+
`ahub source add` registers a bounded file or URL snapshot, and `ahub source list` lists its `src:` registry ID. For profiles that support `plan.sources`, task proposal and acceptance validate each ID against this registry before changing the board or notifying peers. An unknown ID is refused with `ahub source list` as the next step. Source overlaps use the registry IDs; a private task's public plan remains withheld.
|
|
4958
|
+
|
|
4959
|
+
The dashboard's Plan sheet includes a read-only registered-source list with ID, kind, byte size, hash prefix and registration time. It receives only those allowlisted metadata fields through the existing snapshot, with no source content or origin paths.
|
|
4960
|
+
|
|
4961
|
+
Use Capture a request in the same sheet, or `ahub intake`, to stage natural-language work as held draft Backlog cards. Optional source IDs refer to the registered snapshots. The dashboard uses the same Tasks intake path and public task projection as the CLI; nothing is offered until a draft is approved. Inspect drafts in Backlog, then use `ahub intake approve` or `ahub intake discard` in a terminal. A delegated `--live-test` dashboard session cannot create intake drafts. If submission is unconfirmed, read Backlog before trying again to avoid a duplicate request.
|
|
4962
|
+
|
|
4846
4963
|
## Staging work in Backlog (#263)
|
|
4847
4964
|
|
|
4848
4965
|
Use `ahub task propose implement "Later work" --backlog --owner codex` to stage
|
|
@@ -4963,7 +5080,24 @@ reserved peer that cannot take it (offline, paused, excluded, at its WIP limit)
|
|
|
4963
5080
|
refuses the pull before any change, naming the peer and its reason; it is not
|
|
4964
5081
|
passed over to another peer. `ahub route explain` previews the same reserved-only
|
|
4965
5082
|
choice. An unreserved pull keeps reserving a slot as above. A reserved offer that
|
|
4966
|
-
was never started can return untouched
|
|
5083
|
+
was never started can return untouched. Omitting planning fields retains its
|
|
5084
|
+
reservation, so `tasks.auto_pull` can offer it again as soon as the slot is free.
|
|
5085
|
+
|
|
5086
|
+
To park untouched work in one operation, the planner's
|
|
5087
|
+
`hub_backlog_return_untouched` accepts optional `fields` containing only
|
|
5088
|
+
`reserved` (a peer ID or `null`). For example:
|
|
5089
|
+
|
|
5090
|
+
```json
|
|
5091
|
+
{"id":138,"revision":6,"reason":"wait for the person","fields":{"reserved":null}}
|
|
5092
|
+
```
|
|
5093
|
+
|
|
5094
|
+
The return, reservation change, planning revision and previous reservation are
|
|
5095
|
+
saved together before capacity notices or auto-pull run. Read the returned
|
|
5096
|
+
`planningRevision` for a later planning change. Without `fields`, the planning
|
|
5097
|
+
revision and reservation are retained. Reservation updates use the existing
|
|
5098
|
+
person/planner, roster, exclusion and capability checks; a planner cannot clear
|
|
5099
|
+
or replace a person's reservation. The ordinary `ahub backlog return` form keeps
|
|
5100
|
+
its existing reservation-preserving behavior.
|
|
4967
5101
|
|
|
4968
5102
|
Capacity defaults to one per peer. Each declared instance has its own `tasks.wip_limits.<instance>` key. `ahub settings set tasks.wip_limits.codex 2`
|
|
4969
5103
|
uses the existing machine-local registry path; integers 0..32 apply live (the next
|
|
@@ -5469,7 +5603,7 @@ Native launcher connections retry transport timeouts/unclean closes with bounded
|
|
|
5469
5603
|
|
|
5470
5604
|
## amem runtime (agent-mem#13 P4)
|
|
5471
5605
|
|
|
5472
|
-
The hub exact-pins @staix/agent-mem 0.
|
|
5606
|
+
The hub exact-pins @staix/agent-mem 0.20.1 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.
|
|
5473
5607
|
|
|
5474
5608
|
## Backlog issue identity and notes
|
|
5475
5609
|
|
|
@@ -5906,3 +6040,26 @@ kimi: not started: kimi starts in its TUI and the hub could not open a terminal
|
|
|
5906
6040
|
- **Who and when:** only a person's own `ahub up` and the dashboard manager's "start" (which counts as one). An agent's `ahub up` is refused by the CLI before this runs. A daemon restart, a crash recovery, a config reload (`start` applies at the next `ahub up`) and the `ahub up` that an upgrade or recovery relaunches (it carries `AGENTHUB_RECOVERY_OPERATION`) start nothing from the list, and the running hub never reads it. `--live-test` starts none either.
|
|
5907
6041
|
- **What can be listed:** `claude`, `codex`, `kimi`, `pi`, `local` and `jcode`. `qwen` is refused when saved ("the hub never opens its TUI"), as are `agy`, a declared instance, a Claude channel extra, an unknown id and a duplicate, each with a named reason; the loader and the settings writer say the same words. Pi in the list is the user-facing switch; `pi.auto_start` keeps working for configs that have it.
|
|
5908
6042
|
- **Failure is local to one agent:** a refusal, a terminal provider that fails or a request that times out prints its own line and never stops the hub or the other agents. The lines come from the hub's own reply, so a provider's error text stays in `hub.log`.
|
|
6043
|
+
|
|
6044
|
+
## The worktree shelf (#1057)
|
|
6045
|
+
|
|
6046
|
+
Implementers work in `.worktrees/<name>`, and after a guarded merge only the owner removes its local worktree and branch (`docs/sdlc.md`, Merge result and cleanup), so finished worktrees pile up. The shelf shows which ones are finished. It never removes anything itself.
|
|
6047
|
+
|
|
6048
|
+
```
|
|
6049
|
+
ahub worktrees # live worktrees, then the shelf with each settled row's reason
|
|
6050
|
+
ahub worktrees --json
|
|
6051
|
+
ahub worktrees tidy # a preview: what is safe to remove, what is refused and why, and a fingerprint
|
|
6052
|
+
ahub worktrees tidy --confirm <fingerprint> # the person's own terminal: re-reads everything, then removes
|
|
6053
|
+
```
|
|
6054
|
+
|
|
6055
|
+
- **Settled is derived, never stored.** The hub stores facts and two person overrides, and works the groups out on every read. Rules, in order: the main checkout and the declared instance worktrees (`.worktrees/<instance>`) are never shelved; an override that is still in force wins; a merged or closed PR with no work newer than its change time settles the worktree; `worktrees.quiet_days` without activity settles it (`quiet`); everything else is live. A settled row names its reason: `merged`, `closed`, `quiet` or `parked`; a row bound to a PII task shows `settled` and `task: private` instead of its PR reason, task id and PR.
|
|
6056
|
+
- **What counts as activity.** The latest of the HEAD commit time, the mtime of the worktree's own index (uncommitted editing) and the bound task's latest history entry written by anyone but the hub. The hub's own entries (the merge result, the owner notice) are left out, or a merge would always look like newer work. The tidy preview's own git reads run with `--no-optional-locks`, so previewing does not touch the index and make a settled worktree look active. A worktree whose commit time or index could not be read (a failed git call, or the read budget used up) is listed live with `complete: false` and is never shelved by a PR or by quiet time: unknown is not settled.
|
|
6057
|
+
- **Where the PR state comes from.** From the board only: a guarded merge's own record says `merged`. A cancelled task says nothing about its PR, and a task with no record reads `unknown`. Nothing is fetched from GitHub when you open the panel, run `ahub worktrees`, or when the inbox alert is computed.
|
|
6058
|
+
- **Park, Pin and Unset.** The Agents panel offers Park (move a live row to the shelf), Pin (keep a settled row live) and Unset (back to what the rules derive). An override counts only while the worktree has had no newer activity (`lastActiveAt <= at`); later work makes it inert and the next write removes it. They are control operations `worktree_override_set` and `worktree_override_clear`, console role only: an agent's tools connection is refused.
|
|
6059
|
+
- **Refresh PR states.** The one button that reads GitHub, and the control operation `worktrees_refresh_prs` behind it (console role). It reads each bound task's PR with the same `readSdlcPr` the guarded merge uses, at most 8 PRs, 8 s per call and 25 s in all, one refresh at a time, and keeps what it read in the hub's memory (a restart forgets it and those rows read `unknown` again). A PR GitHub could not answer for keeps its old state and is counted as unreadable. The plugin asks you to confirm it first, because it calls GitHub.
|
|
6060
|
+
- **The panel's list.** The Agents view gets a `worktrees` field from a cache at most 30 s old that a background read refreshes: a snapshot never waits for git. Paths are project-relative (or the basename outside the project root), never absolute. The panel shows removal as the command to copy, never as a button.
|
|
6061
|
+
- **The inbox alert.** acon's inbox raises one `alert` item per project when the settled count is above `worktrees.alert_over` (0 never). It carries the count and a link to the Agents panel, nothing else: no path, branch or task.
|
|
6062
|
+
- **Settings.** `worktrees.quiet_days` (default 7, 0 = never shelve by quiet time) and `worktrees.alert_over` (default 10, 0 = never alert), both live, both on the Switches group of `ahub settings` and the dashboard.
|
|
6063
|
+
- **Tidy is the person's.** `tidy` previews each settled row that is safe to remove and each refused row with its reasons: dirty, locked, commits not pushed to the upstream or no upstream, branch not merged into the default branch, the main checkout, an instance worktree, a bound task that is not approved or cancelled, or anything git could not tell. The preview ends with a fingerprint over the rows. `--confirm <fingerprint>` is console class (an agent can only preview, and `--live-test` refuses it), re-reads everything, refuses the whole run if the set changed, and runs exactly two argv shapes per row, `git worktree remove <path>` and `git branch -d <branch>`, then reads each result back. `--force` and `-D` never appear: git itself refuses a dirty tree or an unmerged branch. A worktree edited between the confirm's re-read and the removal is not guarded by anything but git's own refusal.
|
|
6064
|
+
- **The daemon deletes nothing.** The shelf's git port runs only `worktree list --porcelain -z`, `log -1 --format=%ct HEAD` and `rev-parse --absolute-git-dir`, and refuses any other argv before spawning. Removal exists only in the CLI process (`src/cli/worktree-tidy.ts`), which the daemon never imports; `test/worktree-shelf.test.ts` greps the daemon-reachable modules for a removal.
|
|
6065
|
+
- **Limits.** At most 256 worktrees are listed and 1024 overrides read; git reads run 4 at a time under a 3 s total budget (5 s per call), asynchronously, so a slow git never holds the daemon. The quiet threshold is the owner's call after a week of use.
|
package/docs/quickstart.md
CHANGED
|
@@ -17,7 +17,7 @@ ahub setup # installs the channel plugin and a pr
|
|
|
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.30.0
|
|
21
21
|
ahub setup
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -31,6 +31,20 @@ move a running project to a newer release later, run `ahub upgrade` in a
|
|
|
31
31
|
terminal in that project: it reviews the plan with you, applies it and follows
|
|
32
32
|
it; other projects keep their version.
|
|
33
33
|
|
|
34
|
+
## Upgrading to 0.30.0
|
|
35
|
+
|
|
36
|
+
The hub now exact-pins `@staix/agent-mem` 0.20.1 (#1136). A setup receipt written by 0.20.1 can be v2, which 0.20.0 refuses to apply or undo; undo a setup with the release that wrote it.
|
|
37
|
+
|
|
38
|
+
Nothing else changes until you use something new. `ahub worktrees` lists the project's live and settled worktrees (settled: its PR merged or closed with no newer work, or quiet for `worktrees.quiet_days`, default 7), and `ahub worktrees tidy` previews which settled ones are safe to remove, with the reasons for each refused row; only you remove them, with `ahub worktrees tidy --confirm <fingerprint>` in your own terminal, which runs `git worktree remove` and `git branch -d` and never forces (#1057). The dashboard's Agents panel gets a Worktrees section with Park, Pin and "Refresh PR states", and an inbox alert fires above `worktrees.alert_over` (default 10). Pi and the local worker name their own session with `hub_set_title`; `ahub title <peer> <text...>` or the console's `t` editor replaces the name (#1157). A plan's `sources` must now name registered `src:<16 hex>` ids (`ahub source list`), or the proposal or acceptance is refused (#1151). Run agy with `AGY_CLI_DISABLE_AUTO_UPDATE=1`: without it agy replaced its own binary during a launch (#1140).
|
|
39
|
+
|
|
40
|
+
## Upgrading to 0.29.0
|
|
41
|
+
|
|
42
|
+
Upgrade every `amem` that shares your memory home together with the hub: the hub now exact-pins `@staix/agent-mem` 0.20.0, and an `amem` 0.19.0 hook or CLI cannot drain 0.20.0's new hook spool records and can retire them after seven days (#1131). Formats, shards, candidates and indexes are unchanged.
|
|
43
|
+
|
|
44
|
+
A hub-sandboxed peer (Pi, the local worker) can no longer commit, branch, tag, stash, switch, merge, rebase or reset, nor `git add` in a linked worktree: the sandbox refuses writes to refs, HEAD, packed-refs and worktree admin files (#1123). Instead the hub makes a task worktree for its write work (`implement`, `bulk_edit`) at accept and commits and pushes it at `hub_task_done` (#1115, #1129). Where the hub cannot make one (no git repository, no first commit, or a repository config that names a helper, filter or include), that work is not offered to Pi or the local worker, and an assignment to them is refused with the cause; run `git init` and make a first commit, or give the work to Claude, Codex or Kimi.
|
|
45
|
+
|
|
46
|
+
`ahub status --full` shows control-write timing counters, and a slow control write or a blocked event loop leaves a metadata-only record in `hub.log` (#1126). Set `AHUB_CONTROL_WRITE_TIMING=1` for client-side timing on stderr.
|
|
47
|
+
|
|
34
48
|
## Upgrading to 0.28.0
|
|
35
49
|
|
|
36
50
|
`ahub init` now takes flags for the main project settings (#1100, #1107): `--agents <a,b,...|none>`, `--sdlc off|advise|enforce`, `--coordination advisory|turn-free`, `--memory`/`--no-memory`, `--snapshots`/`--no-snapshots`, `--pi`/`--no-pi`, `--specs`/`--no-specs`, `--spec-review off|report|require` and, for a new project only, `--autonomy inherit|off`. On an existing project only a flag you give changes anything, `--dry-run` shows each change as old -> new, and an invalid value is refused with the allowed values. Run at a terminal on a new project with none of these flags and no `--yes`, `ahub init` asks each setting with its default in brackets and shows the plan before it writes anything; `--yes` takes the defaults, and a pipe, a peer or `--dry-run` is never asked (#1110). Design specs are new and on by default (#1097, #1102, #1107). A design spec is a Markdown file with `id` and `type` frontmatter. `ahub specs list|check|covers` reads the specs and checks their links and freshness without a daemon, agents get the read-only `hub_specs`, and `ahub status` adds a specs line when the project has specs. `ahub specs stamp` is your own record, made at a terminal, that you reviewed a spec against HEAD (see [design spec inspection](operations.md#design-spec-inspection)). The next `ahub init` in an existing project adds an `AGENT_HUB_SPECS` block to `AGENTS.md` unless the project set `specs.enabled` to false; `ahub init --no-specs` turns specs off and removes the block.
|
|
@@ -163,7 +177,7 @@ The restarted Claude planner gets the release-train tools (`hub_release_new`, `h
|
|
|
163
177
|
|
|
164
178
|
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`.
|
|
165
179
|
|
|
166
|
-
Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.
|
|
180
|
+
Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.20.1. 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).
|
|
167
181
|
|
|
168
182
|
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:
|
|
169
183
|
|
|
@@ -227,6 +241,7 @@ or set `OMNIROUTE_API_KEY`. The `.agenthub/routing.toml` that `ahub init` writes
|
|
|
227
241
|
| `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 |
|
|
228
242
|
| `ahub status` | peers, queues, pauses; `ahub budget` for quota windows |
|
|
229
243
|
| `ahub usage [--by peer\|task\|issue\|pr\|release\|day\|model]` | tokens per group, each number with its source; `ahub usage limits` for pauses and resets |
|
|
244
|
+
| `ahub worktrees` | live and settled worktrees; `ahub worktrees tidy` previews what is safe to remove, and only you confirm it with `--confirm <fingerprint>` |
|
|
230
245
|
| `ahub agents` | which installed agent CLI versions the hub accepts; `ahub agents trust <id> <version>` accepts an untested one on this machine |
|
|
231
246
|
| `ahub memory profile-check` | a person's read-only check of running memory bindings in the current registry |
|
|
232
247
|
| `ahub ask <question>` | what the board, shared memory and the log say, with the ids the answer rests on |
|
|
@@ -238,7 +253,7 @@ More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-de
|
|
|
238
253
|
|
|
239
254
|
## Shared memory
|
|
240
255
|
|
|
241
|
-
The hub exact-pins the first-party `@staix/agent-mem` 0.
|
|
256
|
+
The hub exact-pins the first-party `@staix/agent-mem` 0.20.1 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.
|
|
242
257
|
|
|
243
258
|
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.
|
|
244
259
|
|
package/docs/sdlc.md
CHANGED
|
@@ -178,7 +178,7 @@ Post-run reads make at most three attempts within a shared six-second budget. On
|
|
|
178
178
|
|
|
179
179
|
Tasks stores host-only `sdlc.merge` evidence bound to the repository, PR and head. Lifecycle tools cannot submit this field, and artifact changes invalidate it. A change during an awaited operation leaves the previous attempt in history without overwriting the replacement artifact. Durable cleanup and owner-notice claims precede those effects. Merged or uncertain attempts are not automatically repeated after restart; a positively observed not-merged result can be retried by an explicit command. A crash before the first post-run record remains an untracked attempt requiring inspection.
|
|
180
180
|
|
|
181
|
-
Remote cleanup reads the merged PR head, repository default, legacy protection and active rulesets. It skips missing, fork, default, protected, moved or unsupported refs. Its only ref write is a single GraphQL compare-and-swap deletion: `beforeOid` is the merged PR head and `afterOid` is zero. A moved head refuses deletion; unknown outcomes stay explicit. The hub sends the owner a public-view notice to remove only its task worktree and local branch when safe. The hub runs no local branch or worktree deletion.
|
|
181
|
+
Remote cleanup reads the merged PR head, repository default, legacy protection and active rulesets. It skips missing, fork, default, protected, moved or unsupported refs. Its only ref write is a single GraphQL compare-and-swap deletion: `beforeOid` is the merged PR head and `afterOid` is zero. A moved head refuses deletion; unknown outcomes stay explicit. The hub sends the owner a public-view notice to remove only its task worktree and local branch when safe. The hub runs no local branch or worktree deletion. Finding the worktrees that are left over is the worktree shelf (`docs/operations.md`, "The worktree shelf (#1057)"): the hub derives which ones are finished and shows them, and removal is the person's own `ahub worktrees tidy --confirm` in a terminal, never a daemon or panel action.
|
|
182
182
|
|
|
183
183
|
## Verdict mirror (#786)
|
|
184
184
|
|
|
@@ -403,7 +403,7 @@ Tracked npm cleanliness compares the cached index to HEAD and raw tracked blob b
|
|
|
403
403
|
|
|
404
404
|
## Release preparation and the guarded tag (#787 P3b)
|
|
405
405
|
|
|
406
|
-
Release preparation is an agent task; the release decision remains the person's. Consent may be recorded by the person or by the configured conductor on the explicit version-naming instruction above; preparation alone grants no consent.
|
|
406
|
+
Release preparation is an agent task; the release decision remains the person's. Consent may be recorded by the person or by the configured conductor on the explicit version-naming instruction above; preparation alone grants no consent. A hub captured before #1120 has no `scripts/check-docs.mjs` in its runtime copy, so `ahub sdlc authorize-release` there refuses with "documentation checker ... is missing from the running hub" (not "stale documentation"): record consent from a hub that carries the checker, either `ahub upgrade` to a release that includes #1120 or a hub started from the candidate checkout with `bun src/cli/main.js`, and never restamp documents to get past it.
|
|
407
407
|
|
|
408
408
|
`bun scripts/release-prepare.ts [--version X.Y.Z] [--dry-run]` is the mechanical half of AGENTS.md "Releasing" steps 1 and 2. On a `release/<version>` branch (it refuses `main`, a detached HEAD, a dirty tree and any other branch name) it reads the commits since the last `v*` tag, applies the rule (any `feat` subject bumps the minor, otherwise the patch; a version below the rule or not newer than the last tag is refused, so is a missing or empty `## Unreleased`), and writes `package.json`, the README `Status:` line, the CHANGELOG section (the Unreleased entries move under the version, Unreleased stays empty), the bundle (`bun run build`) and a verification report skeleton `docs/verification/<date>-<version>.md`. The skeleton lists the pull requests the commits name and the native acceptance receipts, which it reads from `docs/verification/` files added since the tag, never from what an agent writes. It leaves `TODO(agent)` markers for what only a review can state: each PR's review and CI, the document review, the checks and the known gaps.
|
|
409
409
|
|