@staix/agent-hub 0.29.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 +12 -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 +2 -1
- package/docs/agent-notes/tasks.md +4 -2
- package/docs/agent-notes/tests.md +2 -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 +18 -0
- package/docs/dogfood.md +7 -4
- package/docs/operations.md +106 -11
- package/docs/quickstart.md +10 -3
- package/docs/sdlc.md +1 -1
- package/docs/security.md +28 -2
- 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.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-grok-1.0.62-t0.md +150 -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 +193 -29
- 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 +2 -0
- package/src/cli/identity.ts +8 -1
- package/src/cli/main.ts +39 -0
- package/src/cli/worktree-tidy.ts +158 -0
- package/src/cli/worktrees-output.ts +43 -0
- package/src/hub/board.ts +28 -3
- 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/daemon.ts +237 -19
- package/src/hub/dogfood-read.ts +62 -9
- package/src/hub/hub-tools.ts +11 -5
- 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/settings.ts +3 -0
- package/src/hub/tasks.ts +30 -8
- 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/memory/capture.ts +1 -1
- 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/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
|
|
|
@@ -1764,7 +1810,7 @@ ahub memory forget 1a2b3c4d # a person's; also promote, demote, sup
|
|
|
1764
1810
|
|
|
1765
1811
|
`"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
|
|
1766
1812
|
|
|
1767
|
-
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.
|
|
1768
1814
|
|
|
1769
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).
|
|
1770
1816
|
|
|
@@ -2241,7 +2287,7 @@ Run `ahub autonomy on` from a person's terminal. It previews the concrete settin
|
|
|
2241
2287
|
|
|
2242
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.
|
|
2243
2289
|
|
|
2244
|
-
`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.
|
|
2245
2291
|
|
|
2246
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.
|
|
2247
2293
|
|
|
@@ -2386,6 +2432,7 @@ A guarded file edit that the daemon keeps at its accepted value remains visible
|
|
|
2386
2432
|
| Routing | `routing.stay_switch`, `routing.classes.<class>.peers`, `.escalate_to`, `.route`, `.pi_backend` | `routing.local.toml` | at once |
|
|
2387
2433
|
| Switches | `research.enabled`, `approvals.notify`, `snapshots.enabled` | `config.local.json` | live, without disturbing an active turn |
|
|
2388
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 |
|
|
2389
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 |
|
|
2390
2437
|
| Routing | `tasks.wip_limits.<peer>` | `config.local.json` | live |
|
|
2391
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 |
|
|
@@ -3452,7 +3499,7 @@ version is older than the selected running daemon; it installs nothing.
|
|
|
3452
3499
|
| Runtime | Control protocol window | Legacy status field |
|
|
3453
3500
|
| --- | --- | --- |
|
|
3454
3501
|
| 0.12.20 through 0.25.0 | 16 only | `protocol: 16` |
|
|
3455
|
-
| 0.26.0 through 0.
|
|
3502
|
+
| 0.26.0 through 0.30.0 | 16 through 17 | `protocol: 16`, `protocolMin: 16`, `protocolMax: 17` |
|
|
3456
3503
|
|
|
3457
3504
|
New clients choose the highest common protocol. The runtime supports N-1, so the
|
|
3458
3505
|
published protocol-16 client and channel plugin remain usable; unrelated feature
|
|
@@ -4725,7 +4772,7 @@ selected roster and existing capabilities; the TUI is always a person's start.
|
|
|
4725
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.
|
|
4726
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.
|
|
4727
4774
|
|
|
4728
|
-
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
|
|
4729
4776
|
is insufficient: startup verifies its native identity/version and advertised mode
|
|
4730
4777
|
ids before any prompt. The earlier local installation reported CLI 0.25.0 while
|
|
4731
4778
|
its package/ACP source said 0.24.1; that was not a ready identity. The 0.26.0 receipt
|
|
@@ -4776,7 +4823,7 @@ Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or
|
|
|
4776
4823
|
|
|
4777
4824
|
## Optional Antigravity (agy) peer
|
|
4778
4825
|
|
|
4779
|
-
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.
|
|
4780
4827
|
|
|
4781
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`.
|
|
4782
4829
|
|
|
@@ -4905,6 +4952,14 @@ A `schedules` entry in `.agenthub/config.local.json` takes either `every` (an in
|
|
|
4905
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.
|
|
4906
4953
|
- Out of scope: holiday and exchange calendars. A task whose first step finds a non-working day can end itself.
|
|
4907
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
|
+
|
|
4908
4963
|
## Staging work in Backlog (#263)
|
|
4909
4964
|
|
|
4910
4965
|
Use `ahub task propose implement "Later work" --backlog --owner codex` to stage
|
|
@@ -5025,7 +5080,24 @@ reserved peer that cannot take it (offline, paused, excluded, at its WIP limit)
|
|
|
5025
5080
|
refuses the pull before any change, naming the peer and its reason; it is not
|
|
5026
5081
|
passed over to another peer. `ahub route explain` previews the same reserved-only
|
|
5027
5082
|
choice. An unreserved pull keeps reserving a slot as above. A reserved offer that
|
|
5028
|
-
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.
|
|
5029
5101
|
|
|
5030
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`
|
|
5031
5103
|
uses the existing machine-local registry path; integers 0..32 apply live (the next
|
|
@@ -5531,7 +5603,7 @@ Native launcher connections retry transport timeouts/unclean closes with bounded
|
|
|
5531
5603
|
|
|
5532
5604
|
## amem runtime (agent-mem#13 P4)
|
|
5533
5605
|
|
|
5534
|
-
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.
|
|
5535
5607
|
|
|
5536
5608
|
## Backlog issue identity and notes
|
|
5537
5609
|
|
|
@@ -5968,3 +6040,26 @@ kimi: not started: kimi starts in its TUI and the hub could not open a terminal
|
|
|
5968
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.
|
|
5969
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.
|
|
5970
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,12 @@ 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
|
+
|
|
34
40
|
## Upgrading to 0.29.0
|
|
35
41
|
|
|
36
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.
|
|
@@ -171,7 +177,7 @@ The restarted Claude planner gets the release-train tools (`hub_release_new`, `h
|
|
|
171
177
|
|
|
172
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`.
|
|
173
179
|
|
|
174
|
-
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.
|
|
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).
|
|
175
181
|
|
|
176
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:
|
|
177
183
|
|
|
@@ -235,6 +241,7 @@ or set `OMNIROUTE_API_KEY`. The `.agenthub/routing.toml` that `ahub init` writes
|
|
|
235
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 |
|
|
236
242
|
| `ahub status` | peers, queues, pauses; `ahub budget` for quota windows |
|
|
237
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>` |
|
|
238
245
|
| `ahub agents` | which installed agent CLI versions the hub accepts; `ahub agents trust <id> <version>` accepts an untested one on this machine |
|
|
239
246
|
| `ahub memory profile-check` | a person's read-only check of running memory bindings in the current registry |
|
|
240
247
|
| `ahub ask <question>` | what the board, shared memory and the log say, with the ids the answer rests on |
|
|
@@ -246,7 +253,7 @@ More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-de
|
|
|
246
253
|
|
|
247
254
|
## Shared memory
|
|
248
255
|
|
|
249
|
-
The hub exact-pins the first-party `@staix/agent-mem` 0.20.
|
|
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.
|
|
250
257
|
|
|
251
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.
|
|
252
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
|
|
package/docs/security.md
CHANGED
|
@@ -673,7 +673,7 @@ withholds the scoped mode on these writes so an older hook grants nothing too.
|
|
|
673
673
|
|
|
674
674
|
Agent CLI versions (#691). One policy gates the Codex and Kimi fresh reviewers, the headless Claude implementer, Jcode, agy, Qwen (ACP and the dual-output TUI) and Pi (#843): a receipt-verified version passes, Jcode and agy also start an untested version inside their compatible line with a note, and any other version is refused unless the person trusts that exact version on this machine with `ahub agents trust <id> <version>`. The record is `agent-compat.json` in the hub home (`~/.agenthub`), written atomically with mode 600 and at most 64 entries; an unreadable, linked, oversized or invalid record trusts nothing. Agent shells and `--live-test` may read `ahub agents` but cannot trust or revoke. Trust lifts only the version pin: the fresh reviewers' runtime proofs still run before every child, and an untested version's native contract stays unverified.
|
|
675
675
|
|
|
676
|
-
Qwen Code's optional production ACP peer requires the qwen-code native identity, a compat-admitted version (receipt-verified 0.25.0, 0.26.0, 0.26.1 and 0.26.
|
|
676
|
+
Qwen Code's optional production ACP peer requires the qwen-code native identity, a compat-admitted version (receipt-verified 0.25.0, 0.26.0, 0.26.1, 0.26.4 and 0.26.5)
|
|
677
677
|
and advertised mode ids before setting a policy or starting work. Its own tools
|
|
678
678
|
have no hub sandbox; auto-edit approves file edits, yolo every tool. Configured
|
|
679
679
|
never-ask still requires the person's confirmation. qwen_cmd is machine-local and
|
|
@@ -682,7 +682,7 @@ this production table. Startup diagnostics withhold native host/payload details.
|
|
|
682
682
|
|
|
683
683
|
Jcode is optional, source/version-fenced and runs native tools without a hub sandbox or hub permission-mode mapping. .jcode joins the scoped-grant exclusion, including lexical/resolved aliases. Only a person writes its unique project MCP entry; foreign/override/symlink entries refuse. The hub owns a private daemon/socket and ACP group, never the global daemon, and copies no credentials. It accepts a plain jcode release from 0.98.0 up to, not including, 1.0.0 (#529; only 0.98.1, 0.99.0 and 0.99.1 are verified, and another version in that line starts with a note), or an exact version the person trusts (#691), and runs every owned jcode process (probe, serve, ACP and TUI) with `JCODE_NO_TELEMETRY=1`, because jcode's telemetry can report the provider account's email. Native diagnostics withhold payloads/hosts. Hub tools are bound to an owned launch (task 368): the shared project entry names no peer, each owned Jcode process carries its own peer id and launch id, the daemon admits a hub-tools connection for a Jcode peer only with the id of that peer's current owned launch, and a tools-mode server started without a peer id refuses every tool. Extra Jcode instances (#685, at most 8) are declared only through `instances` in an untracked `.agenthub/config.local.json`, start headless, and each needs its own `jcode_home`, which may not be the base home or another instance's, nor nested in or around one, however it is spelled. Unproved conversation loads refuse; no fresh replacement is called a restore. A finished task's advisory about the project root checkout names the branch only after the hub's whole public-text screen (`Tasks.publicMetadataText`: a PII pattern, a secret shape and a project-private path) passes it and it is a plain ref name; otherwise a generic sentence carries no part of it (#572). Native TUI launch exposes its private socket/session tuple only to the authenticated console, bound to the same live owned socket and session after read-only native persistence proof. Tools/status do not receive it. The TUI has no single-writer guard: person input may interleave with ACP. Native policy remains unmanaged and closing the frontend does not stop ACP. An `important` message reaches a busy Jcode as a soft interrupt written to the hub's own private server socket for the owned session (#572); the hub never cancels a turn to deliver, and a steer that was sent but not acknowledged, or whose turn ended first, is held as `needs_review`, never replayed. Jcode has no switch to choose its MCP servers, so the owned serve and ACP processes load every server named in `<JCODE_HOME>/mcp.json` and the project's `.jcode/mcp.json`, `.mcp.json` and `.claude/mcp.json`, besides the hub's own; `ahub doctor` lists their names only. Point `jcode_home` at a separate home, or remove a server from those files, to keep it out.
|
|
684
684
|
|
|
685
|
-
Antigravity (`agy`, #485) is optional, cloud and off roster by default. The launcher accepts the Antigravity CLI 1.4.x line; only 1.4.2 and 1.4.
|
|
685
|
+
Antigravity (`agy`, #485) is optional, cloud and off roster by default. The launcher accepts the Antigravity CLI 1.4.x line; only 1.4.2, 1.4.7 and 1.4.12 have a native receipt ([1.4.7](verification/2026-10-26-agy-1.4.7.md), [1.4.12](verification/2026-11-03-agy-1.4.12-launcher-nonce.md)), so another 1.4.x patch launches with a warning that it is unverified, and every other version is refused before a hub connection or plugin write (#589) unless the person trusts that exact version (#691). It runs native tools under its own unmanaged permissions, without a hub sandbox or hub permission-mode mapping; headless, resume, unattended and native permission flags are refused. Its roles are capped at implementer and verifier, so it never plans, reviews or receives PII work. Only the person's `ahub agy` launcher writes its three plugin files in `.agents/plugins/agent-hub/` (`plugin.json`, `mcp_config.json`, `hooks.json`): linked or foreign entries refuse before any write, cleanup removes only that launch's matching files, and it never writes project-level `.agents/hooks.json` or the person's `~/.gemini` settings. Conductor starts are refused, and a declared agy extra instance is refused at config load (#625). Hook authority (`native_hook_launch`) comes only from that launcher, belongs to the console socket that began it and ends when that socket closes; hook input over 1 MiB is refused, and observations are bound to the daemon, launch, native session and project.
|
|
686
686
|
|
|
687
687
|
Configured ACP adapters (#451 A3) are declared only by the person, in a Git-confirmed untracked `.agenthub/config.local.json`. The whole declaration (command, argv, identity, roles and mode maps) is machine-local authority: a shared or tracked declaration is ignored with a notice, settings never edit it, and changes need a hub restart. The hub runs only the declared argv, never a module or callback. Argv that selects a leader, attach, connect or remote mode is refused, and a Grok declaration needs `--no-leader`. Each start requires the pinned native identity, an exact `session/load` echo on resume, and positive ownership of the spawned process and its original process group; unknown ownership refuses, and stop signals only that verified group. An agent that hands its work to a process outside that group is outside this boundary. Without a mode map native policy is unmanaged, and there is no hub sandbox either way. Configured kinds are cloud peers (never PII), headless only and off roster by default, and the hub makes no quota, context or controlled-recovery claims for them. A read-only instance needs the native read-only mode acknowledged before a prompt and is limited to read and review hub tools, both in the published MCP list and at the host; its native non-read tool requests are rejected, and no setting or runtime change can raise it. These agents' stderr and error text are withheld from logs, and previews redact the executable, argv and session id.
|
|
688
688
|
|
|
@@ -835,6 +835,8 @@ What the sandbox can and cannot write is stated here so nobody relies on more. A
|
|
|
835
835
|
|
|
836
836
|
On decline or cancel the hub removes the worktree and deletes the branch while it is still the empty base. A worktree with uncommitted changes, or that cannot be checked, is never force-removed: it is kept with its branch and reported as a console notice. A branch the hub committed to is kept, because its commit may be pushed and under review. A peer that makes its own worktree (Claude, Codex, Kimi) is untouched, and a PII task never gets a hub worktree. Residual: a same-user process outside the sandbox can still plant a ref under `.git/refs/heads`; the sandbox no longer lets a sandboxed command do it (#1123), and the hub refuses to commit or push on top of a moved ref either way.
|
|
837
837
|
|
|
838
|
+
Worktree shelf (#1057). Apart from the empty hub-made task worktree above, the daemon never removes a worktree or deletes a branch; the shelf only reads and records the person's Park or Pin. `ahub worktrees` and the `ahub worktrees tidy` preview are reads an agent may run outside a private turn; Park, Pin, "Refresh PR states" and `tidy --confirm` are the person's (the console, or the dashboard session the manager forwards for it; a live-test dashboard is refused, and `tidy --confirm` is person-only for an agent identity and refused under `--live-test`). The only removal path is `ahub worktrees tidy --confirm <fingerprint>` in the person's own CLI process (`src/cli/worktree-tidy.ts`, which the daemon does not import). It re-reads every row and refuses the whole run when the fingerprint changed, operates only on a path git itself lists, and runs exactly `git worktree remove <path>` and `git branch -d <branch>`, never `--force` or `-D`. A row is refused when it is the main checkout, an instance worktree, outside the project, dirty, locked, without a branch, unpushed, without an upstream, not merged into the default branch, bound to a task that is not approved or cancelled, or on a branch that changed since the preview, and whenever git cannot tell; a parked row passes the same checks. No read makes a GitHub call; only the explicit refresh does, for at most 8 PRs. A worktree bound to a PII task keeps that binding on the host, so it stays live and tidy refuses it, but its row carries no task id, PR or task state.
|
|
839
|
+
|
|
838
840
|
Refs, HEAD and worktree admin writes (#1123). A hub-sandboxed peer (Pi, the local worker) cannot move what a branch, `HEAD` or a linked worktree points at. The profile (`gitRefRules` in `src/local/deny.ts`, built into `hubWriteRegexes`) refuses every write to `refs/**` (branches, tags, `refs/stash`, remote refs), `packed-refs` (and its lock and new files), `HEAD` (and `HEAD.lock`) and `worktrees/**` (a linked worktree's admin dir: its `HEAD`, `index`, `logs`, anything new, and a new admin dir). The rules sit directly under the git dir, so a project below a directory that happens to be named `refs`, `worktrees`, `HEAD` or `packed-refs` keeps working. They cover a plain `.git`, and each external git dir (the common dir and a linked worktree's own, whether the worktree is inside the project or beside it, and a bare repository's common dir that is not named `.git`). Every name is folded for the code points HFS+ ignores like the other git names, and each regex literal stays under seatbelt's 1024-byte limit at any project depth (`test/sandbox-git-refs.test.ts`, run with the real sandbox-exec in the main checkout, in a hub-made worktree, in a worktree outside its project and in a bare repository's worktree). The hub's own git is hardened and runs outside the sandbox, so #1115's hub commit and push are unaffected.
|
|
839
841
|
|
|
840
842
|
What a sandboxed command can still write under `.git`, each with its reason, probed with the real profile: the main checkout's `index` and `index.lock` (`git add` and `git restore` stage there), `logs/HEAD`, `ORIG_HEAD`, `FETCH_HEAD`, `MERGE_HEAD`, `COMMIT_EDITMSG`, `info/exclude` and `description` (none can run a program or move a branch), and NEW loose objects under `objects/` (a staged blob, #864; existing objects, `objects/info` and `objects/pack` stay refused). Still refused as before: a gitfile, `config`, `config.worktree`, `hooks`, `commondir` (#270). Inside a linked worktree the sandbox cannot write the worktree's own admin dir, so `git add` there fails on its `index.lock`; the working tree itself is writable and `git status`, `diff`, `log`, `show`, `blame`, `ls-files`, `rev-parse`, `for-each-ref` and `cat-file` all still work.
|
|
@@ -1176,3 +1178,27 @@ path and no polling when no real cleanup occurred.
|
|
|
1176
1178
|
Done/discard acknowledgement precedes the background room retry. A network retry
|
|
1177
1179
|
failure or socket loss during that later work cannot report a committed local
|
|
1178
1180
|
disposition as failed.
|
|
1181
|
+
|
|
1182
|
+
## Hub-owned session titles
|
|
1183
|
+
|
|
1184
|
+
`hub_set_title` (#1055) is offered only to fixed Pi/local definitions with a
|
|
1185
|
+
hub-owned title slot. Publication grants no authority: the daemon checks the
|
|
1186
|
+
current adapter/session, private turn, open PII ownership or review and public
|
|
1187
|
+
metadata policy. An agent may write only while the native/current slot remains
|
|
1188
|
+
unnamed. A person's console rename may replace it, but cannot bypass privacy.
|
|
1189
|
+
The title and any unnamed display label are screened again when shown; unknown
|
|
1190
|
+
screening is `[private]`. Title tool inputs/results are excluded from capture
|
|
1191
|
+
and progress observations. No title crosses rooms, changes task/Git/instance
|
|
1192
|
+
records, or causes an extra model call.
|
|
1193
|
+
|
|
1194
|
+
A fallback label is never persisted. Its original message has the existing
|
|
1195
|
+
journal retention; the separate `session-title-inputs.json` stores only peer,
|
|
1196
|
+
title-session, delivery and envelope IDs written by positive delivery
|
|
1197
|
+
acknowledgement, never by a title tool. Restart resolves a still-retained
|
|
1198
|
+
original only for the same title-session ID. A missing or different session,
|
|
1199
|
+
invalid binding or pruned original yields no inherited label. Live status may
|
|
1200
|
+
show it only to the console or configured conductor; other readers see
|
|
1201
|
+
`unnamed`. Metadata screening does not grant audience membership. The label's
|
|
1202
|
+
source note identifies incoming-message text and never attributes it as the
|
|
1203
|
+
recipient peer's own speech. `status.json`, events, logs and memory never
|
|
1204
|
+
receive a derived copy. Removed-instance and Local bindings are not retained.
|
package/docs/smoke.md
CHANGED
|
@@ -38,7 +38,7 @@ Autonomy T4 (#999 AC8): [2026-11-02 live inventory](verification/2026-11-02-auto
|
|
|
38
38
|
| Character glyphs in real terminals and tmux (#280) | Console attention; Dashboard character | agent-evidence / person-verdict | glyph rendering in physical terminals |
|
|
39
39
|
| Console Settings panel in a native terminal (#439) | Settings reload and console fixture | agent-evidence / person-verdict | the panel as a person sees it |
|
|
40
40
|
| Reviewer pool native legs (#519) | Reviewer pool native legs | agent-executable | after #783 ships |
|
|
41
|
-
| Antigravity TUI close (#485) | Antigravity P1 | agent-executable | |
|
|
41
|
+
| Antigravity TUI close (#485) | Antigravity P1 | agent-executable | launcher close leg passed on 2026-11-03 ([receipt](verification/2026-11-03-agy-tui-close.md)); still open: `hub_send` and a board read or proposal through the TUI, a real account |
|
|
42
42
|
| Managed Pi live receipts (#418 AC8) | none yet (issue #418) | person-only, then agent-executable | the person opts in to a check runner and answers the approvals |
|
|
43
43
|
| Kimi credential probe (#285 AC9) | Kimi usage counting | person-only | the owner's approval of the probe |
|
|
44
44
|
| Six role instances (#525-6, hub card #138 I4) | Six role instances (#525-6) | person-only | native terminal/account starts, the person's sandbox and approval choices, and the live six-instance verdict |
|
|
@@ -2025,7 +2025,8 @@ Kimi usage ceiling: 2.2.0 print stream-json exposes no token counts. Keep unobse
|
|
|
2025
2025
|
|
|
2026
2026
|
## Antigravity P1 (#485)
|
|
2027
2027
|
|
|
2028
|
-
- Run agy on the 1.4.x line (1.4.2 and 1.4.
|
|
2028
|
+
- Run agy on the 1.4.x line (1.4.2, 1.4.7 and 1.4.12 verified; other patches warn, #589); verify its executable/version and keep the actual TUI/IDE leg separate from the account-free T0 transport receipts ([1.4.2](verification/2026-10-19-agy-p1-t0.md), [1.4.7](verification/2026-10-26-agy-1.4.7.md), [1.4.12](verification/2026-11-03-agy-1.4.12.md) and its [launcher nonce leg](verification/2026-11-03-agy-1.4.12-launcher-nonce.md)).
|
|
2029
|
+
- The hub launcher's own close leg ran in a scratch project with the real `ahub agy` and a fixture provider ([2026-11-03 receipt](verification/2026-11-03-agy-tui-close.md)): the launch slot is held while agy starts and runs, a normal `/exit` releases it so the next launch is admitted, only the managed three-file plugin is removed, and the real Gemini config hashes are unchanged. Set `AGY_CLI_DISABLE_AUTO_UPDATE=1` for any further live agy run: without it agy replaced `~/.local/bin/agy` during that run.
|
|
2029
2030
|
- With a reviewed compatible daemon running and agy explicitly on roster, the person runs `ahub agy` in a terminal. Confirm peer `agy` is pull-only, native permissions unmanaged and no hub sandbox/budget source is claimed.
|
|
2030
2031
|
- In the native TUI call `hub_inbox`, `hub_send`, and a permitted board read/proposal within a non-PII task. Confirm the tool audience and actor remain `agy`, the native model consumes the tool results, and no unsolicited push or PII task text reaches it.
|
|
2031
2032
|
- End the TUI normally. Confirm its group/socket detaches and only its matching managed three-file plugin is cleaned up; unrelated project/global settings remain unchanged.
|
|
@@ -2163,3 +2164,13 @@ account fixture needs the person's account setup. Ask the planner before any
|
|
|
2163
2164
|
quota-heavy run. Never publish prompts, tokens, credentials, endpoints, native
|
|
2164
2165
|
transcripts or session ids as evidence. This slice implements no task `exec`,
|
|
2165
2166
|
routing policy or matrix runner.
|
|
2167
|
+
|
|
2168
|
+
## Pi session title restart receipt (#1055, #1143)
|
|
2169
|
+
|
|
2170
|
+
- [ ] Unverified: in a real managed Pi session, call `hub_set_title`, verify its
|
|
2171
|
+
native name and DOING, restart into that same saved session and verify the
|
|
2172
|
+
name survives. A second agent call must return `already_named`; a person
|
|
2173
|
+
rename must replace the name and remain final against the agent.
|
|
2174
|
+
- The fake-free Pi 1.5.0 setter/readback/reopen API probe is recorded separately
|
|
2175
|
+
in `docs/verification/2026-11-03-pi-title-api.md`; it does not complete this
|
|
2176
|
+
model-backed managed-session restart receipt. Track the live leg in #1143.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: Office view of live agent work in the dashboard
|
|
3
3
|
date: 2026-10-12
|
|
4
4
|
project: agent-hub
|
|
5
|
-
status: phases 1-
|
|
5
|
+
status: phases 1-5 implemented (Flat and Isometric office, backlog wall, release docks and planner marks); AC9 live browser look remains unverified
|
|
6
6
|
issue: 264
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -55,7 +55,8 @@ asset is copied.
|
|
|
55
55
|
latch, the settle rule. No daemon change.
|
|
56
56
|
3. Optional snapshot fields `turn`, `checking`, `links` and what they draw.
|
|
57
57
|
4. The Isometric projection of the same model.
|
|
58
|
-
5. Backlog wall, release docks and the planner's desk,
|
|
58
|
+
5. Backlog wall, release docks and the planner's desk, from the board
|
|
59
|
+
planning fields that #263 and #469 added (decisions below).
|
|
59
60
|
|
|
60
61
|
Phase 1 decisions within the spec:
|
|
61
62
|
|
|
@@ -209,6 +210,73 @@ Phase 4 decisions within the spec:
|
|
|
209
210
|
- Existing theme tokens, public-view privacy, counts/placement classifications,
|
|
210
211
|
animations, reduced motion, keyboard activation and mode cookie remain.
|
|
211
212
|
|
|
213
|
+
Phase 5 decisions within the spec (designed 2026-11-03, hub task 311;
|
|
214
|
+
implemented by hub task 682, with AC9 live browser look still open):
|
|
215
|
+
|
|
216
|
+
- Phase 5 needs no daemon change. `ui_snapshot` already carries everything:
|
|
217
|
+
- every board task, backlog cards included, with `rank`, `priority`,
|
|
218
|
+
`reserved`, `release`, `pinned`, `plannedStart` and `deps` next to the
|
|
219
|
+
public title;
|
|
220
|
+
- `releases[]`, the `tasks.releaseList` rows, with `id`, `name` (already
|
|
221
|
+
`[withheld]` when not nameable), `state`, `order`, `cut` and the scope
|
|
222
|
+
`tasks[]` as `{ id, state, deps }`;
|
|
223
|
+
- `status.roleInfo[peer].flowRoles`, which names the planner.
|
|
224
|
+
The model reads these by allowlist. It never reads a release `goal`, `train`,
|
|
225
|
+
the `afterCut` lists, task `detail`, `lifecycle` or `codeGroup`, and the
|
|
226
|
+
marker test grows to cover them.
|
|
227
|
+
- **Backlog wall.** A room named "Backlog" before To do in the fixed room
|
|
228
|
+
order, with placement `room:backlog`. Today `counts.backlog` is counted and
|
|
229
|
+
placed nowhere; from phase 5 these tasks get placed.
|
|
230
|
+
- Cards are ordered by `rank` ascending (no rank last), then `priority`
|
|
231
|
+
ascending (none last), then id. The cap is 8 cards, as in every room; the
|
|
232
|
+
rest is "+N more", which sets the board's existing `backlog` state filter.
|
|
233
|
+
- A card shows its id and public title, like other room cards. It adds up to
|
|
234
|
+
three marks, each with a shape and text in the accessible name:
|
|
235
|
+
- the reserved peer's colour chip and name;
|
|
236
|
+
- a pin for `pinned`;
|
|
237
|
+
- "waits", when a dep is not approved or `plannedStart` is in the future
|
|
238
|
+
(the date only, never the time).
|
|
239
|
+
- The wall count equals `taskProgress(tasks).counts.backlog`, pinned by the
|
|
240
|
+
existing counts test.
|
|
241
|
+
- A pulled card moves from the wall to To do through the phase-2 transform
|
|
242
|
+
transition, with no new motion code.
|
|
243
|
+
- **Release docks.** A strip below the rooms, beside the Done shelf. It has
|
|
244
|
+
one dock per release in state `planning`, `active` or `frozen`, ordered by
|
|
245
|
+
`order` then id; `shipped` and `dropped` releases get none. The cap is 3
|
|
246
|
+
docks, then "+N releases", which switches the board's View to "By release".
|
|
247
|
+
- A dock shows the release name, its state as a word, `approved / scope`
|
|
248
|
+
from its `tasks[]`, and a thin bar of the same ratio. It also shows the
|
|
249
|
+
`cut` date when set.
|
|
250
|
+
- Cards are not duplicated into docks: a card stays in its room. A card in
|
|
251
|
+
a docked release carries the release's ordinal (1 to 3) as a small tag
|
|
252
|
+
with the name in its accessible name.
|
|
253
|
+
- Activating a dock sets the board's existing `task-release-filter` to that
|
|
254
|
+
release and scrolls to the board, as card activation does for its row.
|
|
255
|
+
- **Planner's desk.** The desk of each peer whose `flowRoles` include
|
|
256
|
+
`planner` gets a planner badge: a shape plus "planner" in its accessible
|
|
257
|
+
name. A count joins it: the backlog cards with no `rank` and no `reserved`,
|
|
258
|
+
that is, the cards still waiting for planning. A peer with no desk gets no
|
|
259
|
+
badge, and the count then appears on the wall's header. The planner is a
|
|
260
|
+
mark on the existing desk. It is not a separate desk and claims no seat.
|
|
261
|
+
- **Isometric.** The wall is an ordinary room tile and the docks are slab
|
|
262
|
+
tiles like the shelf, through the same `officeProject`. Phase 4's fit rule
|
|
263
|
+
applies: cards that do not fit are counted in "+N more".
|
|
264
|
+
- **Privacy.** A PII backlog card is already a `[pii]` stub in the snapshot;
|
|
265
|
+
its reserved chip and marks still show, because they carry ids only. A
|
|
266
|
+
release name that is not nameable stays `[withheld]`.
|
|
267
|
+
- **Page-size bound.** This replaces the issue's original 30 KB office budget,
|
|
268
|
+
which was historical (see the phase 4 accounting) and is long exceeded by
|
|
269
|
+
unrelated features. The served page is `renderDashboard().html` with the
|
|
270
|
+
models injected. Measured on main a51c8fc7 (2026-11-03): 259,254 bytes raw,
|
|
271
|
+
70,237 gzip; `src/ui/index.html` alone is 236,071 bytes.
|
|
272
|
+
- The phase-5 PR measures the served page at its merge base and at its head,
|
|
273
|
+
raw and gzip, and states both deltas in the PR body.
|
|
274
|
+
- Phase 5 may add at most 12,000 bytes raw and 3,500 bytes gzip. Beyond
|
|
275
|
+
that, the PR drops art polish first, then trims the dock bar, before it
|
|
276
|
+
asks the person to raise the bound.
|
|
277
|
+
- No standing page-size test is added. Other dashboard features grow the
|
|
278
|
+
same page, and a global cap would block them for an office budget.
|
|
279
|
+
|
|
212
280
|
## Verification
|
|
213
281
|
|
|
214
282
|
- `test/office-model.test.ts`: mapping fixture, counts equality with
|
|
@@ -239,8 +307,23 @@ Phase 4 decisions within the spec:
|
|
|
239
307
|
and overlap/cohort links against a real daemon, pins `PROTOCOL` (16) and
|
|
240
308
|
`EVENTS_SCHEMA` (1), and proves a PII task keeps its stub, refuses a
|
|
241
309
|
non-local owner and joins no link.
|
|
310
|
+
- Phase 5 (implemented with the model and renderer regression tests):
|
|
311
|
+
- wall placement and order (rank, priority, id) with the cap and "+N more";
|
|
312
|
+
- wall count equals `counts.backlog`;
|
|
313
|
+
- the reserved, pin and waits marks;
|
|
314
|
+
- dock selection by state and order with the 3-dock cap and the approved /
|
|
315
|
+
scope ratio;
|
|
316
|
+
- the release ordinal tag on cards;
|
|
317
|
+
- the planner badge and the unplanned count, including the no-desk fallback
|
|
318
|
+
to the wall header;
|
|
319
|
+
- the marker test extended to release `goal`, `train`, `afterCut`, task
|
|
320
|
+
`lifecycle` and `codeGroup`;
|
|
321
|
+
- in `test/office-view.test.ts`, "+N more", dock activation setting
|
|
322
|
+
`task-release-filter` and the "By release" switch, plus a pulled card
|
|
323
|
+
animating from the wall to To do.
|
|
242
324
|
- The live browser look (two agents working, both themes, console open) is
|
|
243
|
-
recorded in `docs/smoke.md` as unverified for phase 1.
|
|
325
|
+
recorded in `docs/smoke.md` as unverified for phase 1. #273 is closed, so
|
|
326
|
+
AC9's browser look stays with #264 itself.
|
|
244
327
|
|
|
245
328
|
|
|
246
329
|
## Merge review corrections
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 0.30.0 release verification
|
|
2
|
+
|
|
3
|
+
This record covers release preparation and source review. It claims no installation, no running-hub upgrade to 0.30.0 and no live TUI launch.
|
|
4
|
+
|
|
5
|
+
## Candidate
|
|
6
|
+
|
|
7
|
+
Version 0.30.0, prepared from main 397b1bd7 (20 commits since v0.29.0, 7 of them `feat`; bump rule: minor). The release commits carry the version, the CHANGELOG section, the bundle and the documentation stamps.
|
|
8
|
+
|
|
9
|
+
## Reviews
|
|
10
|
+
|
|
11
|
+
Pull requests named by the commits since v0.29.0: #1160, #1159, #1158, #1157, #1156, #1155, #1153, #1150, #1151, #1149, #1152, #1148, #1146, #1142, #1141, #1140, #1138, #1139, #1136.
|
|
12
|
+
|
|
13
|
+
Each merged with `gh pr merge --squash --match-head-commit <head>` after a `hub_review` approval, with exact-head CI green on ubuntu and macOS (19 checks pass, 2 skipped, seeded guards included), no unresolved review thread and no pending change request. Approvals by claude unless named:
|
|
14
|
+
|
|
15
|
+
- #1136 (task 679, agent-mem 0.20.1) at 1346c687; #1138 (680, #1137) at 756d72e5; #1139 (325, #635 T0) at f83ea324; #1141 (681) at a283bf4a; #1151 (683, #1144) at 4930af65; #1152 (682, #264) at e6878d11; #1155 (687, #1154) at 6717f1a1; #1159 (691) at 15d25ae6; #1160 (692) at ea3ee6ab.
|
|
16
|
+
- After one changes_requested round each: #1153 (686, #1147) at fd8a3286; #1156 (688, #1057 T1-T2) at 58afb35b; #1157 (689, #1055) at bd79846b; #1158 (690, #1057 T3) at a56ff7f6.
|
|
17
|
+
- Approved by the person, since claude owned or the hub named the person as reviewer: #1140 (443) at 4b652581, #1142 (311, design) at 0f0e805c, #1149 (685, dogfood receipt) at aa20ae95.
|
|
18
|
+
- Task 684 shipped three PRs under one approval bound at #1146's head d303a050. #1148 and #1150 were read in that review at earlier heads (f281e23b, 3f19f9fc), then rebased for conflicts and merged at 26766aaa and 3da9d6d6 after their own exact-head CI. The commits added after the read are a one-line receipt wording fix (26766aaa, `docs/verification/2026-11-03-pi-150-compat.md`) and a regenerated bundle hunk (3da9d6d6, `plugins/agent-hub/server.js`, 3 lines); every other commit is the reviewed change rebased. These two are the only merges bound to an approval at an earlier head.
|
|
19
|
+
|
|
20
|
+
## Native acceptance receipts
|
|
21
|
+
|
|
22
|
+
Receipts added under `docs/verification/` since v0.29.0: `docs/verification/2026-11-03-agy-1.4.12-launcher-nonce.md`, `docs/verification/2026-11-03-agy-1.4.12.md`, `docs/verification/2026-11-03-agy-tui-close.md`, `docs/verification/2026-11-03-grok-1.0.62-t0.md`, `docs/verification/2026-11-03-pi-150-compat.md`, `docs/verification/2026-11-03-pi-title-api.md`, `docs/verification/2026-11-03-qwen-0265-acp.md`, `docs/verification/2026-11-03-qwen-0265-dual-output.md`, `docs/verification/dogfood/2026-11-03.md`, `docs/verification/pi-150-model-free.ts`, `docs/verification/pi-150-native.mjs`, `docs/verification/pi-150-title-api.mjs`.
|
|
23
|
+
|
|
24
|
+
This list is read from the repository, never written by hand. Native acceptance and the person's release consent are separate records: consent is `ahub sdlc authorize-release 0.30.0`, recorded by the person or the unique configured conductor only on the person's explicit release instruction naming the release in its own session (never a hub/task/review/file/peer relay), and is not recorded in this file. The tag run refuses without it.
|
|
25
|
+
|
|
26
|
+
## Document review
|
|
27
|
+
|
|
28
|
+
`node scripts/check-docs.mjs --require-fresh` reported 14 stale documents. Each was read against `git log 0d0a362c..HEAD -- <its paths>` (`src/cli/help.ts` against its own stamp 3efa678d), the fixes went in as 8612cfd7, and all 14 were restamped at 8612cfd7:
|
|
29
|
+
|
|
30
|
+
- `README.md`: the Operations list names the worktree shelf; the report link points at this file.
|
|
31
|
+
- `docs/quickstart.md`: install line `#v0.30.0`, an "Upgrading to 0.30.0" section, the agent-mem pin 0.20.1 in two places, and an `ahub worktrees` row in the working-day table.
|
|
32
|
+
- `docs/operations.md`: 0.30.0 in the header and the protocol table (protocol unchanged, 16 through 17), agent-mem 0.20.1 in two places that still said 0.18.0, agy 1.4.12 verified with `AGY_CLI_DISABLE_AUTO_UPDATE=1`, a Settings row for `worktrees.quiet_days` and `worktrees.alert_over`, the PII row and `--no-optional-locks` notes in the shelf section, and an Office phase 5 paragraph.
|
|
33
|
+
- `docs/security.md`: agy 1.4.12 receipt, and a worktree shelf paragraph (removal only in the person's CLI, never forced; console-only overrides and refresh; the refusal list; PII rows).
|
|
34
|
+
- `src/cli/help.ts`: `tidy --confirm <fingerprint> [--json]`, which `main.ts` honours. `ahub worktrees` and `ahub title` were already listed and match.
|
|
35
|
+
- `docs/agent-notes/adapters.md`: agy 1.4.12, and the session-title writer rule (#1055).
|
|
36
|
+
- `docs/agent-notes/daemon.md`: the conductor frame of an incoming-label DOING row, the label audience and `session-title-inputs.json`, and a worktree shelf rule.
|
|
37
|
+
- `docs/agent-notes/tasks.md`: `hub_set_title` tool placement, and the plan-sources validation rule (#1144).
|
|
38
|
+
- `docs/agent-notes/tests.md`: the #1057 tests that cut `daemon.ts`, `index.html` and `sdlc.ts` by text.
|
|
39
|
+
- No change needed: `docs/agent-notes/README.md`, `benchmarks.md`, `budget.md`, `bus.md`, `local-worker.md` (each read; the commits in range do not change what they state).
|
|
40
|
+
|
|
41
|
+
## Checks
|
|
42
|
+
|
|
43
|
+
- `node scripts/check-docs.mjs --require-fresh`: `docs: OK (0 stale documents)` after the restamp at 8612cfd7.
|
|
44
|
+
- Full `scripts/check.sh` on dgx02 (`remote_dev.py verify`) at b39870aa (tree 4fef8b16): typecheck (`bun x tsc --noEmit`), the bundle check (`bun scripts/build.mjs --check`), `package: OK (770 files, @staix/agent-hub@0.30.0)`, `roles: OK`, and 11229 pass, 101 skip, 0 fail across 872 files; `check: OK`. Later commits on the release branch change only this report.
|
|
45
|
+
- The release PR's exact-head CI on ubuntu and macOS is the gate for the merge.
|
|
46
|
+
|
|
47
|
+
## Known gaps, not blocking
|
|
48
|
+
|
|
49
|
+
- No installation, running-hub upgrade to 0.30.0 or live TUI launch was done for this record.
|
|
50
|
+
- Office phase 5's live two-agent, both-theme browser look (#264 AC9) is unverified.
|
|
51
|
+
- #1057: the owner confirms `worktrees.quiet_days` after a week of use; the first real `ahub worktrees tidy --confirm` on this repository has not run.
|
|
52
|
+
- #1055 AC7, a live managed Pi restart with a named session, stays in #1143.
|
|
53
|
+
- agy: `hub_send` and a board call through a real-account TUI (#485 AC3) are unverified. qwen-dual 0.26.5 is not promoted (Q2 fails, identically on the 0.26.1 control).
|
|
54
|
+
- `splitBacklog` stores its parts' plans without `validatePlanSources`; acceptance rechecks the stored plan, so an unknown source is still refused before work starts, but a split child can wait in Backlog holding one. Not a release blocker; filed as #1161.
|