@staix/agent-hub 0.23.1 → 0.25.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 +24 -0
- package/README.md +32 -5
- package/docs/agent-notes/adapters.md +5 -2
- package/docs/agent-notes/bus.md +1 -0
- package/docs/agent-notes/daemon.md +16 -2
- package/docs/agent-notes/tasks.md +9 -2
- package/docs/agent-notes/tests.md +3 -0
- package/docs/dogfood.md +16 -2
- package/docs/memory.md +1 -1
- package/docs/operations.md +198 -5
- package/docs/profiles.md +2 -0
- package/docs/quickstart.md +19 -4
- package/docs/security.md +225 -8
- package/docs/specs/2026-09-19-agent-hub-design.md +54 -1
- package/docs/specs/2026-09-19-multi-project-design.md +12 -1
- package/docs/specs/2026-11-01-research-campaigns-design.md +351 -0
- package/docs/verification/2026-10-31-0.24.0.md +63 -0
- package/docs/verification/2026-10-31-claude-implementer-2.1.316.md +65 -0
- package/docs/verification/2026-11-01-0.25.0.md +91 -0
- package/docs/verification/claude-shell-wrapper-native.py +1 -1
- package/docs/verified.json +31 -15
- package/package.json +4 -3
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +5120 -4710
- package/src/adapters/claude-channel.ts +29 -6
- package/src/adapters/compat.ts +3 -3
- package/src/adapters/definitions/native-cli-claude-setup.ts +4 -0
- package/src/adapters/definitions/native-cli-doctor.ts +30 -0
- package/src/adapters/jcode.ts +3 -0
- package/src/adapters/registry.ts +1 -1
- package/src/cli/acon-register.ts +29 -0
- package/src/cli/autonomy-homes.ts +33 -0
- package/src/cli/autonomy-offline.ts +75 -0
- package/src/cli/autonomy-projects.ts +103 -0
- package/src/cli/autonomy.ts +44 -0
- package/src/cli/claude-homes.ts +123 -0
- package/src/cli/claude-profile-hook.ts +130 -0
- package/src/cli/handoff-args.ts +27 -0
- package/src/cli/handoff-output.ts +25 -0
- package/src/cli/help.ts +8 -4
- package/src/cli/identity.ts +8 -1
- package/src/cli/main.ts +174 -33
- package/src/cli/output.ts +8 -5
- package/src/cli/schedule-output.ts +8 -4
- package/src/cli/setup-homes.ts +46 -0
- package/src/cli/setup.ts +1 -1
- package/src/cli/study-output.ts +71 -0
- package/src/cli/study.ts +58 -0
- package/src/cli/task-output.ts +1 -0
- package/src/hub/action-class.ts +203 -14
- package/src/hub/action-enforce.ts +8 -6
- package/src/hub/action-policy.ts +95 -9
- package/src/hub/autonomy-consent.ts +173 -0
- package/src/hub/autonomy-defaults.ts +58 -0
- package/src/hub/autonomy.ts +232 -0
- package/src/hub/board.ts +871 -2
- package/src/hub/channel-project.ts +61 -0
- package/src/hub/config-apply.ts +3 -2
- package/src/hub/confirmation-matrix.ts +202 -0
- package/src/hub/control-client.ts +10 -1
- package/src/hub/daemon.ts +546 -27
- package/src/hub/envelope.ts +2 -0
- package/src/hub/events.ts +4 -1
- package/src/hub/execution-budget.ts +12 -0
- package/src/hub/handoff.ts +126 -0
- package/src/hub/hub-tools.ts +12 -2
- package/src/hub/manager.ts +64 -57
- package/src/hub/no-writes.ts +1 -1
- package/src/hub/path-policy.ts +12 -8
- package/src/hub/project.ts +14 -5
- package/src/hub/provenance.ts +30 -0
- package/src/hub/research-campaign.ts +265 -0
- package/src/hub/research-experiments.ts +445 -0
- package/src/hub/restart.ts +26 -0
- package/src/hub/schedules.ts +210 -9
- package/src/hub/session-identity.ts +49 -0
- package/src/hub/settings.ts +105 -8
- package/src/hub/task-repository.ts +11 -6
- package/src/hub/tasks.ts +894 -22
- package/src/hub/ui.ts +15 -6
- package/src/memory/capture.ts +2 -2
- package/src/ui/index.html +5 -3
- package/src/ui/office-space.ts +118 -0
- package/src/ui/plugin.ts +293 -0
- package/templates/AGENTS.block.md +1 -0
- package/templates/presets/autonomous.json +161 -0
- package/templates/presets/confirmation-matrix.json +943 -0
- package/templates/profiles/general.json +1 -1
- package/templates/profiles/research.json +4 -4
- package/templates/profiles/writing.json +1 -1
- package/templates/roles/research/analyst.md +1 -0
- package/templates/roles/research/fact-checker.md +1 -0
- package/templates/roles/research/research-lead.md +1 -0
- package/templates/roles/research/researcher.md +1 -0
- package/templates/roles/research/statistician.md +1 -0
package/docs/operations.md
CHANGED
|
@@ -557,7 +557,7 @@ and so is every help entry the gate has no class for yet;
|
|
|
557
557
|
|
|
558
558
|
| Command | Class | Why |
|
|
559
559
|
| --- | --- | --- |
|
|
560
|
-
| `ahub doctor [--json] [--full] [--color=...]` | Allowed | a read-only check of tools, daemon, plugin, gateway, models and memory |
|
|
560
|
+
| `ahub doctor [--json] [--full] [--color=...]` | Allowed | a read-only check of tools, daemon, plugin, gateway, models and memory; the `memory capture: codex` and `memory capture: kimi` rows come from agent-mem's setup state (`amem setup <tool> --json` on PATH, a preview that writes nothing), as set up, `amem setup <tool> --apply` needed, client missing, or unknown when `amem` is missing, refuses or prints no setup plan (#1008) |
|
|
561
561
|
| `ahub doctor --stale-anchors [--json]` | Allowed | a bounded read-only report of memory symbol anchors at current HEAD |
|
|
562
562
|
| `ahub queue list [--peer <id>] [--json] [--full] [--color=...]` | Allowed | public queue metadata only; held bodies and resolution remain conductor operations |
|
|
563
563
|
| `ahub roster [--json] [--color=...]` | Allowed | public roster status; add/remove retain conductor admission |
|
|
@@ -573,6 +573,7 @@ and so is every help entry the gate has no class for yet;
|
|
|
573
573
|
| `ahub task cancel\|label\|role <id> ...` | Allowed | the daemon decides per task (#933): `label` and `role` only on a task the caller owns, `role` not while it is in review, and `cancel` by the `hub_task_cancel` rule (the planner's own unaccepted backlog or proposed work) |
|
|
574
574
|
| `ahub deliverables [--task <id>] [--approved] [--check] [--json]` | Allowed | only the rows `hub_task_show` would show the caller, through the same public screening (#933) |
|
|
575
575
|
| `ahub room list [--json]`, `ahub room status [<name>] [--json]` | Allowed | room metadata only; every other `room` form, the inbox included, stays Console |
|
|
576
|
+
| `ahub study show [<id> \| --after <id>] [--json] [--color=...]` | Allowed | the same read as `hub_study_show`: a private campaign, task or source shows ids, counts and states only; `study draft\|revise\|approve\|approve-protocol\|close` stay Console (#930) |
|
|
576
577
|
|
|
577
578
|
`backlog list`, `release list` and `sdlc costs|metrics` retain their existing
|
|
578
579
|
planner/person policy. Their CLI forms stay Console for ordinary agents; a
|
|
@@ -926,6 +927,37 @@ Incompatible or unverified processes are shown explicitly and are never killed b
|
|
|
926
927
|
PID-name matching. See the operations guide and the
|
|
927
928
|
[multi-project specification](specs/2026-09-19-multi-project-design.md).
|
|
928
929
|
|
|
930
|
+
## acon console plugin (#935, #1012)
|
|
931
|
+
|
|
932
|
+
`ahub setup` registers agent-hub as a plugin of the family console
|
|
933
|
+
([agent-console](https://github.com/STAIxBWLB/agent-console), `acon ui`). It writes
|
|
934
|
+
`$AGENTHUB_HOME/console/plugins/ahub.json` (default `~/.agenthub/console/plugins/ahub.json`;
|
|
935
|
+
the directory 0700, the file 0600, replaced atomically) naming the installed module
|
|
936
|
+
`@staix/agent-hub/ui-plugin` and its sha256, and prints `acon plugin registered`, `acon plugin
|
|
937
|
+
up to date` or why it was not registered. acon reads the file at its next start and marks the
|
|
938
|
+
plugin stale when the module changed after setup, so run `ahub setup` again after each upgrade.
|
|
939
|
+
|
|
940
|
+
- **Panels.** The plugin's panels are the dashboard's seven views, and the panel is the `ahub ui`
|
|
941
|
+
page itself, following acon's theme. It reaches project hubs only through the manager's own
|
|
942
|
+
listing and forwarding (`ahub ui --all`): registered project and instance ids, the manager's
|
|
943
|
+
closed action list and the seven view names. There is no new protocol or action.
|
|
944
|
+
- **Inbox.** acon's inbox lists each running project's pending approvals (Allow once / Deny,
|
|
945
|
+
answered with the hub's own `permit` and an option the request offers) and in-review tasks whose
|
|
946
|
+
reviewer is you (Open board). A local-worker or Pi approval stays deny-only there, as on the
|
|
947
|
+
dashboard: answer it with `ahub permit` after `ahub tail`.
|
|
948
|
+
- **Confirmation.** `stop`, `permit`, `send`, the settings writes (`setting`, `setting_undo`,
|
|
949
|
+
`setting_reload`, `config_edit_apply`), `start_peer`, `backlog_split` and the inbox's Allow once
|
|
950
|
+
and Deny answer `needsConfirm` with a preview first; acon runs them after you confirm.
|
|
951
|
+
Previews and the other dashboard actions run directly, as on the page.
|
|
952
|
+
- **Space.** The plugin feeds acon's Space view from the dashboard's office model
|
|
953
|
+
(`src/ui/office-space.ts`): peers are actors (state from condition, approvals and review, with
|
|
954
|
+
approval, queue, paused and mode marks), the office rooms are queue, work, review and done zones,
|
|
955
|
+
tasks are cards, and overlap, conflict and cohort links and recent message arcs are links. Ids
|
|
956
|
+
are project-prefixed, every running project's scene is merged within acon's caps (32 actors, 200
|
|
957
|
+
cards, 64 links, newest links kept), and a project that has not answered within about 3 s is left
|
|
958
|
+
out of that poll. Only labels and states reach the scene, never message bodies, task details,
|
|
959
|
+
approval titles or reasons; a PII task's card shows the `[pii]` stub.
|
|
960
|
+
|
|
929
961
|
## Install and start
|
|
930
962
|
|
|
931
963
|
Use Bun 1.4.2 or newer. Source checks and CI use the version pinned in
|
|
@@ -942,7 +974,9 @@ ahub up
|
|
|
942
974
|
|
|
943
975
|
`ahub init` writes the project configuration and managed instruction blocks.
|
|
944
976
|
Run it after an upgrade when those blocks need refreshing. `ahub setup`
|
|
945
|
-
updates the
|
|
977
|
+
installs or updates the Claude plugin and a project-neutral PreToolUse hook in each
|
|
978
|
+
Claude configuration home in use (see "Machine autonomy and Claude homes"), and
|
|
979
|
+
registers the acon console plugin (see "acon console plugin"). Keep `ahub console` open when a local worker
|
|
946
980
|
may request an approval.
|
|
947
981
|
|
|
948
982
|
`.agenthub/config.json` can be committed and shared. The fields that choose
|
|
@@ -1134,6 +1168,15 @@ and start): a committed file must not choose commands the hub runs. Keys that
|
|
|
1134
1168
|
are not task classes are ignored with a log line. A hub stopped mid-check leaves
|
|
1135
1169
|
the task in progress (`check interrupted`); the owner marks it done again.
|
|
1136
1170
|
|
|
1171
|
+
The owner may call `hub_task_done` again while the task is in review, with a
|
|
1172
|
+
different full lowercase commit SHA in `refs.commit` (#1000, #1021). It replaces the
|
|
1173
|
+
delivered artifact, not a verdict: the reviewer gets a fresh request for the new
|
|
1174
|
+
head, the old CI watch is replaced, stale observed, reviewed and merge evidence is
|
|
1175
|
+
cleared, and open Important findings, spec acceptance and the rejection count stay.
|
|
1176
|
+
A configured completion check first returns the task to in progress until it passes.
|
|
1177
|
+
The same head, a malformed SHA, another owner or a running check refuse without
|
|
1178
|
+
effect, and a verdict started on the old request no longer applies.
|
|
1179
|
+
|
|
1137
1180
|
While the project root checkout is on a branch other than its default
|
|
1138
1181
|
(`origin/HEAD`, else `main`), finishing a task adds `the main checkout is on
|
|
1139
1182
|
<branch>; move the work to a worktree under .worktrees/` to the owner's result
|
|
@@ -1426,6 +1469,60 @@ ahub research backfill # build this project's records once from even
|
|
|
1426
1469
|
ahub task label 12 reverted # a later verdict (ok, regressed, reverted, incomplete, wrong, abandoned)
|
|
1427
1470
|
```
|
|
1428
1471
|
|
|
1472
|
+
## Research campaigns: `ahub study` (#930)
|
|
1473
|
+
|
|
1474
|
+
A research campaign splits one question on an approved parent task into bounded units, each a task with
|
|
1475
|
+
its own sources and required output. Nothing happens until a campaign is drafted, and the `ahub research`
|
|
1476
|
+
telemetry above is unrelated. The contract, its bounds and the slices are in the
|
|
1477
|
+
[research campaigns spec](specs/2026-11-01-research-campaigns-design.md); the worked three-source example is in
|
|
1478
|
+
[profiles](profiles.md).
|
|
1479
|
+
|
|
1480
|
+
```bash
|
|
1481
|
+
ahub study draft 12 contract.json # store revision 1 as a draft; creates no task
|
|
1482
|
+
ahub study revise rc-0123456789ab 1 next.json # store the next draft; a stale revision refuses
|
|
1483
|
+
ahub study approve rc-0123456789ab 2 # person only: create the unit tasks as Backlog cards
|
|
1484
|
+
ahub study show [rc-0123456789ab] # list campaigns (50 per page, --after continues) or one projection
|
|
1485
|
+
ahub study close rc-0123456789ab 2 --reason "answered"
|
|
1486
|
+
ahub study approve-protocol <64-hex hash> # person only: approve one exact experiment protocol
|
|
1487
|
+
```
|
|
1488
|
+
|
|
1489
|
+
- **Contract.** The JSON names the question, scope, exclusions, registered source ids, 1 to 32 units
|
|
1490
|
+
(round, question, perspective, required output, sources, dependencies and a purpose: discovery,
|
|
1491
|
+
independent check, analysis or synthesis), deliverable sections, a stop policy (`maxUnits`,
|
|
1492
|
+
`maxFollowUpRounds` up to 5, a deadline at most 90 days after approval) and an optional execution budget.
|
|
1493
|
+
A contract over its bounds refuses whole, naming the field.
|
|
1494
|
+
- **Who does what.** Draft and revise are the person's (`ahub study`) or a configured planner's
|
|
1495
|
+
(`hub_study_draft`, `hub_study_revise`); they store drafts only. Approve, approve-protocol and close are
|
|
1496
|
+
console commands. Approval is the only step that creates unit tasks: they go to Backlog and the planner
|
|
1497
|
+
offers them through its ordinary pull; the campaign never assigns owners or approves a task. Re-running
|
|
1498
|
+
approve on an approved revision creates nothing.
|
|
1499
|
+
- **Dispatch gate.** Before a unit task is offered, assigned, pulled or handed to another owner the hub
|
|
1500
|
+
re-reads the campaign and holds the task with a reason when its revision is no longer the latest approved
|
|
1501
|
+
one, the deadline has passed or the stop policy is exceeded. A newer draft holds older bound work until it
|
|
1502
|
+
is approved, and an owner offer held this way is re-offered after approval, across a restart too. A hold
|
|
1503
|
+
never stops a native turn already running.
|
|
1504
|
+
- **Handoffs and coverage.** The current in-progress owner of a unit records `hub_study_handoff`: evidence per
|
|
1505
|
+
source, unresolved questions, contradictions and limitations, or `insufficientEvidence`. `ahub study show` and
|
|
1506
|
+
`hub_study_show` report per unit its round, task state, handoff completeness, covered sources and duplicate
|
|
1507
|
+
discovery assignments, the budget support label per resource (`enforceable`, `advisory`, `unknown` or
|
|
1508
|
+
`unavailable`) and why dispatch is held. A follow-up round needs every discovery unit of the previous round
|
|
1509
|
+
settled by a complete handoff or `insufficientEvidence`.
|
|
1510
|
+
- **Budgets.** A contract's `budget: { id, hardCap: [...] }` names an existing execution budget. With a non-empty
|
|
1511
|
+
`hardCap`, approval refuses unless the budget is enabled, every capped resource has a limit and is not
|
|
1512
|
+
`tokens`, and at least one of its peers is instrumented (today `pi` and `local`); every later dispatch and
|
|
1513
|
+
owner change rechecks that same budget. The ledger is shared with the peers' other work.
|
|
1514
|
+
- **Experiments.** Protocols, comparison plans and attempts are stored with their provenance (`declared`,
|
|
1515
|
+
`host-observed` from a check receipt or a hub-hashed deliverable), and `ahub study approve-protocol` binds an
|
|
1516
|
+
approval to one exact protocol hash and its evaluator; a changed protocol needs its own approval. The hub
|
|
1517
|
+
never ranks results. This release has no hub tool or CLI that records experiments; they are host storage
|
|
1518
|
+
for the slices that follow.
|
|
1519
|
+
- **Privacy.** A campaign whose parent task is PII, or that names a private source, is private: every view keeps
|
|
1520
|
+
ids, counts, states and provenance and stubs its text as `[pii]`. Study tool arguments and results are kept out
|
|
1521
|
+
of hub-managed memory capture.
|
|
1522
|
+
- **Upgrades.** The daemon advertises `research_records`, `research_dispatch`, `research_dropped_offers`,
|
|
1523
|
+
`research_experiments` and `research_comparisons`. While the matching rows exist, a restart, upgrade or
|
|
1524
|
+
recovery onto a release without the feature is refused.
|
|
1525
|
+
|
|
1429
1526
|
## Hub memory
|
|
1430
1527
|
|
|
1431
1528
|
The hub opens the selected amem memory profile under `memoryHome()` (default `~/.agenthub/memory/`), with no claude-mem worker dependency ([how it works](memory.md)): notes saved
|
|
@@ -1441,7 +1538,7 @@ ahub memory forget 1a2b3c4d # a person's; also promote, demote, sup
|
|
|
1441
1538
|
|
|
1442
1539
|
`"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
|
|
1443
1540
|
|
|
1444
|
-
The exact-pinned `@staix/agent-mem` 0.
|
|
1541
|
+
The exact-pinned `@staix/agent-mem` 0.18.0 resolves `AMEM_HOME`, then `$AGENTHUB_HOME/memory`, then `~/.agenthub/memory`. An absent `M/profile.json` selects shared v1; an explicit generation selects `M/generations/G` with the package's readonly legacy bridge. All daemon memory consumers and the hub memory/goal CLI use that selected profile. Invalid metadata or a missing selected generation makes native memory unavailable while the bus and board continue; there is no fallback to legacy writes. Inspect the daemon's memory binding/availability before interpreting missing memory as an empty store.
|
|
1445
1542
|
|
|
1446
1543
|
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).
|
|
1447
1544
|
|
|
@@ -1777,6 +1874,32 @@ Only ignored, untracked `.agenthub/config.local.json` can hold `action_policy`.
|
|
|
1777
1874
|
|
|
1778
1875
|
The ledger asks first and after the approved class budget is spent. Adapter integrations must request that class allowance explicitly; an ordinary one-time answer does not seed the cache, and a cached budget never suppresses a prompt required by the native mode. One approval includes its own invocation; budget zero asks for every invocation. A fresh native session resets counters, and status polls do not bind sessions. A command with no classed literal prefix retains native permission handling; around a shell expansion the literal words are classed, and where the opaque part could change the class the strictest reachable class applies (#756, #762; [security](security.md)). This foundation never changes a sandbox or bypasses a denied permission; per-adapter enforcement tests land with their integrations.
|
|
1779
1876
|
|
|
1877
|
+
### Floor policy: ordinary development work does not ask (#999 T3)
|
|
1878
|
+
|
|
1879
|
+
`action_policy.floor: true` in the untracked `.agenthub/config.local.json` stops the always-ask policy from asking about ordinary development work, and changes nothing else. It is off by default, so a machine without it behaves exactly as above; `ahub autonomy on`, and `ahub init` inheriting a machine opt-in, set it. It applies live through the confirmed terminal reload, like the rest of `action_policy`.
|
|
1880
|
+
|
|
1881
|
+
With the floor on, these run without a prompt wherever the hub sees the call first:
|
|
1882
|
+
|
|
1883
|
+
- `git push` of a literal, non-default branch to `origin`, from inside the execution root (`git push origin feat/x`, `-u`, `HEAD`, `feat/x:feat/x`, `refs/heads/feat/x`, `git -C <subdir> push ...`).
|
|
1884
|
+
- `gh pr create`, `comment`, `review` and `merge` in the project's own GitHub repository, with no `--repo` or URL naming another one and never with `--admin`.
|
|
1885
|
+
|
|
1886
|
+
These still ask, with the class they always had, and so does anything the classifier cannot decide:
|
|
1887
|
+
|
|
1888
|
+
- Any force push (`--force`, `-f`, `+refspec`, `--force-with-lease`, `--force-if-includes`), a delete (`:branch`, `--delete`), `--mirror`, `--all`, `--prune`, `--no-verify` and a push option.
|
|
1889
|
+
- A push to the default branch (`main`, `master` and whatever the remote names its default, in any letter case, as `refs/heads/...` or `heads/...`, or as `HEAD` while it is checked out), a push of a tag (`v1`, `refs/tags/...`, `--tags`, `--follow-tags`, or a bare name that is also a local tag), a ref outside `refs/heads`, a remote other than `origin`, and a bare `git push` or `git push origin`, which follow `push.default`.
|
|
1890
|
+
- `gh release *`, `npm`, `bun`, `pnpm`, `yarn` and `cargo publish`, deletion outside the execution root, `gh issue` and `gh gist` calls, `gh pr close|edit|reopen|delete`, any write to another repository, mail and posting tools.
|
|
1891
|
+
- An expansion in a position that decides the outcome (`git push origin $B`, `gh pr create --repo $R`), a wrapper the classifier cannot read (`env`, `sudo`, `timeout`, `xargs`, a leading `VAR=value`), `-c`, `--git-dir` and `--work-tree`, and a directory the classifier cannot place (`cd /elsewhere`, `cd $D`). A command whose class cannot be decided keeps the strictest class it might reach (#756, #762).
|
|
1892
|
+
|
|
1893
|
+
Facts the floor needs come from the host, never from the agent: the default branch from the authoritative GitHub remote read the task shell uses (not a local `origin/HEAD`; read at start and at every `action_policy` reload, and unknown until it answers, so every push asks until then), the project's own repository from its `origin`, whether a name is also a local tag, and the branch checked out in the directory. A directory counts only when git proves its top level is the peer's execution root and its `origin` is the project's repository, so a nested clone keeps asking. A fact that is missing, unreadable or unproven keeps the call asking. The policy flag is the only switch: floor facts never widen a policy that did not set `floor`, and a disabled policy asks nothing as before. With the floor on, `publish`, `external-write` and `destroy` ask whatever `always_ask` says: a coarse selector cannot hand the floor's own classes back (`install` still follows `always_ask`).
|
|
1894
|
+
|
|
1895
|
+
The floor also reads the checkout's push configuration and gh's default, per call. A plain `git push origin <branch>` keeps asking when `remote.origin.pushurl` or a `url.<base>.pushInsteadOf` rewrite sends it anywhere but the project's own GitHub repository (the effective push URLs are read, every one of them, not the fetch URL), when `push.followTags`, `push.pushOption`, `push.recurseSubmodules`, `remote.origin.push` or `remote.origin.mirror` can add tags, options or refs to it, or when any of those reads fails. An unqualified `gh pr ...` asks for every peer whose shell environment the hub cannot see (Claude, Codex, Kimi, Qwen, Jcode, agy), because a `GH_REPO` exported there would redirect it and the hub cannot read it; only an explicit own `--repo`, `-R` or pull request URL runs. For Pi and the local worker, whose command environment the hub builds, an unqualified call runs only when `origin` is the checkout's only remote, no `gh repo set-default` marker names another repository, and the hub's own environment sets no `GH_REPO`, `GH_HOST` or `GH_ENTERPRISE_TOKEN`; a call that names the project's own repository does not depend on gh's default. A wrapper (`env`, `sudo`, `timeout`, `xargs`, a leading `VAR=value`) takes the floor away from a shell it wraps. A `git fetch`, a test or build run (`bun test`, `bun run build`) or `rg --pre` earlier on the same line also ends the floor for the rest of the line, because it can create tags or run the agent's own code. A `gh pr` call is read option by option: an option's value (a `--body` holding a pull request URL) never selects a repository, and an option the floor does not know asks. One classification reads at most 16 distinct facts through one shared budget (every git read and the project origin query alike), answers an identical read once and answers none after 2.5 s, so a long chain of pushes cannot hold the daemon; past the bound a fact is unknown and the call asks. A command earlier on the same line that can change those facts (`git config`, `git remote`, `git checkout`, `git tag`, `export GH_REPO=...`, `gh repo set-default`, any redirect, a script, an unlisted program) ends the floor for the rest of the line; `git add`, `git commit`, `git status`, `git diff`, `git log`, `git fetch`, `bun test`, `echo` and a push the floor itself allows do not.
|
|
1896
|
+
|
|
1897
|
+
Where the hub cannot see a call first (Codex in `never-ask`, Kimi in `auto`, Jcode, a session without the hub hook), the floor cannot be enforced by the hub. `ahub status` says so on that peer's action policy row, with `floor on:` and the structural guards the floor rests on, which the hub names and has not verified: GitHub branch protection on the default branch (force push, default-branch and tag pushes), release only through `ahub sdlc authorize-release` and the OIDC tag workflow (`gh release`, release tags), and the peer's native sandbox (deletion outside the project, writes to another repository). A missing guard is for the person to report. Status marks the floor as a weakening on every policy row (`attention`), like any other policy that asks less.
|
|
1898
|
+
|
|
1899
|
+
The floor changes approval prompts only. No sandbox, deny list, PII rule, path guard or trust check changes, and the person-only flow (release tag consent, logins and trust settings) stays the person's.
|
|
1900
|
+
|
|
1901
|
+
A project whose raw `config.json` or `config.local.json` names `action_policy.floor` at all (true or false, enabled or not, ignored as a shared-file key or not) cannot be upgraded or recovered onto a release that predates the key, because that release rejects an unknown `action_policy` key and the project would not load there. The daemon advertises the `action_policy_floor` feature, and a controlled recovery (`prepare`, `commit` and a target-checking `inspect`) refuses a target without it, naming `target lacks action_policy_floor`, before any effect. A project without the floor is unaffected.
|
|
1902
|
+
|
|
1780
1903
|
## Permission modes for running peers
|
|
1781
1904
|
|
|
1782
1905
|
Use a plain terminal to inspect or change a running peer:
|
|
@@ -1878,6 +2001,39 @@ permission_mode (peer/from/to) with no tool arguments under events schema 1.
|
|
|
1878
2001
|
The optional control requests preserve PROTOCOL; an older hub answers unknown
|
|
1879
2002
|
and the CLI advises upgrading.
|
|
1880
2003
|
|
|
2004
|
+
### Where a person is asked to confirm: the inventory (#999 T0)
|
|
2005
|
+
|
|
2006
|
+
`templates/presets/confirmation-matrix.json` lists every place a person is asked to confirm during a standard task, for each agent kind (claude, codex, kimi, qwen, jcode, pi, local, agy) and each environment (plain terminal, Orca, headless). Each row names what is asked, which keys control it today (`permission_modes.<peer>`, `permission.<peer>`, `action_policy`, `tasks.auto_pull`, `task_sweep.auto_reassign`, `peers.<peer>.start_mode`, `terminal.open`, the peer's native config, and the launch and merge keys), whether the hub sees the call before it runs (`yes`, `partial`, `no`, `unknown`) and who asks (the hub console, the native TUI, both, or nobody). The data is model-free: it was read from the code and from this guide, and a fact that could not be established is the word `unknown` in the structured field (`hubSeesBeforeRun` or `askedBy`) and in the row's `unknowns` list, never in prose alone. A native TUI asker is claimed only on a row that is TUI-only. Qwen's dual-output TUI has separate rows for a turn the hub delivered (the hub asks) and a turn the person typed (only Qwen's own prompt).
|
|
2007
|
+
|
|
2008
|
+
The inventory changes no default itself. The project autonomy status below reads its confirmation facts and unknowns. `test/confirmation-matrix.test.ts` fails when a kind in the adapter catalog has no row in an environment it can run in, when the matrix's facts about a kind (forms, pull-only forms, conductor start, whether the hub maps a mode) differ from its `AdapterDefinition`, when a row names a key the matrix does not describe, or when a cited source line no longer exists. Adding a peer kind means adding its rows there. `templates/presets/autonomous.json` and `ahub autonomy status` use this inventory.
|
|
2009
|
+
|
|
2010
|
+
### Project autonomy: one preset and one confirmation (#999 T1)
|
|
2011
|
+
|
|
2012
|
+
Run `ahub autonomy on` from a person's terminal. It previews the concrete settings and their apply timing, then confirms once; a changed file, preset plan or configuration revision requires a fresh preview; `ahub autonomy on --yes` supplies that confirmation for a typed command. The shipped `templates/presets/autonomous.json` holds the kind and environment rows. This project receives `tasks.auto_pull`, the task sweep switches, `action_policy.floor`, supported permission defaults and start defaults through the existing validated settings writer.
|
|
2013
|
+
|
|
2014
|
+
`ahub autonomy off` removes the fixed shipped preset keys and retained consent, regardless of missing, forged or stale ownership metadata, so the local permission and task-flow values fall back to their inherited defaults. Unrelated settings stay. Reapplying on over unverified metadata overwrites the requested preset keys and issues fresh metadata. Authenticated metadata preserves prior originals for precise `ahub settings undo` after the person types `autonomy`; if its private undo witness does not verify, undo removes the fixed preset keys and clears consent instead, and reports that fallback. A precise authenticated undo still refuses if the file changed since that write. A preset write made while the hub was stopped (offline on, a stopped `--all-projects` target, init inheritance) has no undo witness, so a later undo takes this fallback. Project metadata proves no approval.
|
|
2015
|
+
|
|
2016
|
+
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.
|
|
2017
|
+
|
|
2018
|
+
`ahub autonomy status` prints each peer's current effective mode, the preset's requested next-start default and every current floor class: hub-enforced, a named verified structural guard, or not enforced with a reason. `--json` returns the same report as data. 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.
|
|
2019
|
+
|
|
2020
|
+
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.
|
|
2021
|
+
|
|
2022
|
+
Live config switches apply through scoped reload now. Permission and start defaults apply at the next peer start; an active native turn keeps its policy. `ahub autonomy on` writes one action_policy key, `action_policy.floor: true` (#999 T3, see "Floor policy"), and `off` removes it; it writes no other action_policy key. Status takes each floor class from the running policy and where the hub sees that peer's calls: hub-enforced only for a peer whose calls the hub sees first while `action_policy` asks for the class, otherwise not enforced with the reason, naming the guard the class rests on and that the hub has not verified it. A class with no named guard (package publish, mail and posting) says so. The hub never reports a structural guard as holding on its own. The shipped ask default, sandbox, deny, PII and trust rules stay. Machine-wide defaults, `--all-projects`, init inheritance and Claude profile-home setup are described in "Machine autonomy and Claude homes" below.
|
|
2023
|
+
|
|
2024
|
+
### Machine autonomy and Claude homes (#999 T2)
|
|
2025
|
+
|
|
2026
|
+
`ahub autonomy on [--yes]` also writes the machine opt-in to `~/.agenthub/defaults.json` (or the selected hub home), and `off` disables that default. The file holds only its schema and opt-in; the shipped preset remains the source of settings. It is written as an owner-only 0600 regular file. Unsafe ownership, writable permissions, links, malformed schema or a location inside a project make the file ignored with a notice. A machine with no trusted opt-in keeps the shipped ask behavior. `settings undo` affects the project write, not this machine file.
|
|
2027
|
+
|
|
2028
|
+
Add `--all-projects` to apply on or off to every registered project. On previews all targets before one confirmation. A live hub uses its existing console transaction; a stopped project, with or without `--all-projects`, uses the same preset planner, validated writer and fixed off-key list while holding its registry claim. No daemon is started to write settings. Preview refusals prevent on from changing any target; apply failures name the affected projects and report the partial result. Off disables the machine default even when an unavailable project cannot be updated. Manual changes to fixed preset keys are removed by off, as in the project command.
|
|
2029
|
+
|
|
2030
|
+
A newly initialized `ahub init` project inherits a trusted machine opt-in and says so. Refreshing an existing project does not reapply the default. Offline apply and init create no HMAC consent or witnesses. Offline off may only revoke existing consent under the stopped project's registry claim; a revocation failure names the project and reports failure rather than off success. At startup the daemon can create retained permission consent only when the trusted machine opt-in exists and the local never-ask value exactly matches the preset plan for the environment. Explicit Orca/CI evidence selects those rows; a detached daemon otherwise uses terminal defaults. Without both facts, the ordinary console confirmation remains. Project metadata never supplies machine opt-in authority.
|
|
2031
|
+
|
|
2032
|
+
`ahub setup` selects the explicit `CLAUDE_CONFIG_DIR`, otherwise an existing default Claude home (or the not-yet-created default when no other home is selected), plus distinct homes proven in use by live registered Claude launcher records. It does not scan arbitrary profile directories. Each native plugin command receives that home's environment. One confirmation covers plugin setup and a project-neutral PreToolUse hook while preserving unrelated hooks and statusLine settings. The profile fallback requires the inherited hub state and peer identity and does nothing for a managed launch that already has its session hook, preventing duplicate delivery. Installing a hook proves configuration, not live enforcement.
|
|
2033
|
+
|
|
2034
|
+
`ahub autonomy status [--json]` includes the machine default and each discovered Claude home's plugin/hook state. Missing, unsafe, stale, unavailable or incomplete evidence is explicit; a missing selected home is reported without starting a native inventory command that could create it. The native Orca zero-prompt receipt remains T4.
|
|
2035
|
+
|
|
2036
|
+
|
|
1881
2037
|
## Change the participating peers while the hub runs
|
|
1882
2038
|
|
|
1883
2039
|
`ahub roster` lists every known peer, whether it participates, its start mode,
|
|
@@ -4263,6 +4419,22 @@ A bundled adapter module is authorized by the person with `adapter_modules` (at
|
|
|
4263
4419
|
- Refresh instructions with init and restart the daemon/MCP clients to apply their resolved contracts. Existing flow-role and executable-check authority remains in `roles`/trusted `checks`. Native model/account evidence remains unverified.
|
|
4264
4420
|
|
|
4265
4421
|
|
|
4422
|
+
## Calendar schedules: `cron` and `tz` (#1017)
|
|
4423
|
+
|
|
4424
|
+
A `schedules` entry in `.agenthub/config.local.json` takes either `every` (an interval, `<n>m|h|d`, 15 minutes at least) or `cron`, never both. `cron` ties the run to the clock:
|
|
4425
|
+
|
|
4426
|
+
```json
|
|
4427
|
+
{ "schedules": [{ "id": "digest", "cron": "30 7 * * 1-5", "tz": "Asia/Seoul", "class": "plan", "title": "Morning digest" }] }
|
|
4428
|
+
```
|
|
4429
|
+
|
|
4430
|
+
- **The expression** is the standard five fields, minute, hour, day of month, month, day of week, with numbers, lists (`1,15`), ranges (`1-5`) and steps (`*/15`, `10-50/10`). Day of week 0 and 7 are Sunday. There are no seconds, no year, no `@daily` macros and no names (`MON`, `jan`). When both day fields are restricted a day matches if either does (the classic rule); a field that begins with `*` leaves the other to decide.
|
|
4431
|
+
- **`tz`** is an IANA zone name (`Asia/Seoul`, `America/New_York`) and applies to `cron` only. Without it the machine's own zone is used. An unknown zone is refused with the entry named.
|
|
4432
|
+
- **Daylight saving, one rule.** A local time the clock skips runs at the next valid minute of that day; a local time the clock repeats runs once, at its first occurrence.
|
|
4433
|
+
- **Too frequent.** An expression that can fire more often than every 15 minutes (`* * * * *`, `*/5 * * * *`, `0,10 7 * * *`) is refused when the config loads, naming the schedule, as is one that never fires (`0 0 31 2 *`).
|
|
4434
|
+
- **Everything else is as for `every`.** A schedule never runs at first sight; a hub that was down or held through several fire times proposes one task when it can, not one per missed fire; a budget pause or hold skips and counts the tick; no second task while the first is open. `ahub schedule list`, `ahub status` and the dashboard show the expression and the next run in the schedule's zone, for example `2026-11-02 07:30 Asia/Seoul`.
|
|
4435
|
+
- **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.
|
|
4436
|
+
- Out of scope: holiday and exchange calendars. A task whose first step finds a non-working day can end itself.
|
|
4437
|
+
|
|
4266
4438
|
## Staging work in Backlog (#263)
|
|
4267
4439
|
|
|
4268
4440
|
Use `ahub task propose implement "Later work" --backlog --owner codex` to stage
|
|
@@ -4743,7 +4915,7 @@ Default-branch capture runs only at daemon startup when a Claude implementer is
|
|
|
4743
4915
|
|
|
4744
4916
|
Project Git retains the core policy that clears credential.helper and core.askpass; an HTTPS push needing those helpers may fail, rather than importing credentials or relaxing that policy. Task branch/config proof reads are bounded synchronous reads (1.5 seconds per reader); slow or unknown evidence asks. The existing sandbox profile discovery is also synchronous; moving it to an asynchronous inventory proof with a shared deadline remains a follow-up. The nonce is visible in a permission response, so it proves a bounded grant rather than native-dispatch provenance.
|
|
4745
4917
|
|
|
4746
|
-
The [native permission receipt](verification/2026-10-23-headless-claude-permissions.md) covers Claude Code 2.1.309, and the [2.1.310 receipt](verification/2026-10-26-claude-implementer-2.1.310.md) repeats it on 2.1.310 (with 2.1.309 as a control), and the [2.1.314 receipt](verification/2026-10-31-claude-implementer-2.1.314.md) repeats it and the host-wrapper procedure on 2.1.314 (with 2.1.310 as a control), each with a deterministic loopback fixture and no real account/model call. It is not sandbox proof or a runtime receipt gate. The real account/model/person interaction remains a separate live leg.
|
|
4918
|
+
The [native permission receipt](verification/2026-10-23-headless-claude-permissions.md) covers Claude Code 2.1.309, and the [2.1.310 receipt](verification/2026-10-26-claude-implementer-2.1.310.md) repeats it on 2.1.310 (with 2.1.309 as a control), and the [2.1.314 receipt](verification/2026-10-31-claude-implementer-2.1.314.md) repeats it and the host-wrapper procedure on 2.1.314 (with 2.1.310 as a control), and the [2.1.316 receipt](verification/2026-10-31-claude-implementer-2.1.316.md) repeats both on 2.1.316 (with 2.1.314 as a control), each with a deterministic loopback fixture and no real account/model call. It is not sandbox proof or a runtime receipt gate. The real account/model/person interaction remains a separate live leg.
|
|
4747
4919
|
|
|
4748
4920
|
A headless Claude reviewer is run by the hub instead (task 223): declare
|
|
4749
4921
|
`"claude-review": { "kind": "claude", "roles": ["reviewer"], "start_mode": "headless" }`
|
|
@@ -4881,7 +5053,7 @@ Native launcher connections retry transport timeouts/unclean closes with bounded
|
|
|
4881
5053
|
|
|
4882
5054
|
## amem runtime (agent-mem#13 P4)
|
|
4883
5055
|
|
|
4884
|
-
The hub exact-pins @staix/agent-mem 0.
|
|
5056
|
+
The hub exact-pins @staix/agent-mem 0.18.0 for recall, curated evidence and local deterministic capture. No runtime call reaches a claude-mem worker; `memory.worker_url` is ignored. The person's `ahub memory import claude-mem` remains explicit and off by default. Existing profile, alias, PII and private-turn fences still apply. `ask --remember` and context checkpoints propose machine-local candidates, never automatic curated evidence. See [memory integration](memory.md#in-process-recall-and-capture-agent-mem13-p4) for changed behavior and bounded-view ceilings.
|
|
4885
5057
|
|
|
4886
5058
|
## Backlog issue identity and notes
|
|
4887
5059
|
|
|
@@ -5274,3 +5446,24 @@ Lists are complete up to 1,100 rows. If an all-room list exceeds that limit, the
|
|
|
5274
5446
|
CLI explicitly asks you to choose a room name; it never silently truncates.
|
|
5275
5447
|
ponytail: pagination is later work; a filtered room's 100 unread plus 1,000
|
|
5276
5448
|
settled stubs fit the current response ceiling.
|
|
5449
|
+
|
|
5450
|
+
## Handing work to another project (#604, agent-hub#1030)
|
|
5451
|
+
|
|
5452
|
+
Work that belongs to another repository that runs agent-hub on this machine goes onto that repository's board, not into this session. Its own roles plan, implement and review it, and each state change it reaches is reported back here. The first case: after a library you maintain publishes a release, raising its exact pin in a consumer belongs on the consumer's board.
|
|
5453
|
+
|
|
5454
|
+
```
|
|
5455
|
+
ahub task handoff --project <root|id> [<class>] <title...> [--path <p>]... [--issue <n>] [--task <n>] [--detail <text>]
|
|
5456
|
+
```
|
|
5457
|
+
|
|
5458
|
+
- `--project` is the other project's canonical root or its id from `ahub projects`. It must be registered and its hub must be running (`ahub up` in that project). Nothing is queued: a hub that is not running is refused with that action.
|
|
5459
|
+
- A feature or behavior change first gets a spec issue in the other repository: pass its number as `--issue`. A mechanical chore (an exact version pin, a regenerated file) goes straight to a task.
|
|
5460
|
+
- `--path` names files in the other project, repository-relative (no absolute path, `~` or `..`). `--task` names your own task this comes from, so a `[pii]` one is refused.
|
|
5461
|
+
- `ahub task handoff` is the person's command (an agent's shell is refused it as a console command). Agents use `hub_task_handoff` (the same fields) when they hold the planner or conductor role; `hub_task_handoffs` and `ahub board --handoffs` list what this project handed over and the last state each target reported.
|
|
5462
|
+
|
|
5463
|
+
What the other project sees: an ownerless proposed task, made by its hub, whose detail ends with where it came from; `ahub board` and `ahub task show` there name the origin project and peer. Its own routing offers it as it would a local proposal. The requesting peer has no identity or authority there: it cannot accept, review, approve, assign or cancel.
|
|
5464
|
+
|
|
5465
|
+
What comes back: each change is recorded in `ahub board --handoffs`, and an agent that handed the task over also gets one `kind: task` message per change, `agent-hub task 123 accepted`, `in review`, `approved: PR #7 at <sha>`, `declined` or `cancelled` (a handoff you made from the terminal sends you no message: read the list). It carries an event name, a PR number and a full head, never the other project's text. If this project's hub was stopped meanwhile, it asks each running target hub where its open handoffs stand when it starts again; a target that is down then is asked at the next start.
|
|
5466
|
+
|
|
5467
|
+
Refusals, each named with the action: an unregistered target, this very project, a hub that is not running, a request over 8 KiB or with an unknown field, a caller that is not a planner, the conductor or the person, a private (PII) turn, a `[pii]` task named with `--task`, text that matches the target's PII patterns or that the target's screen cannot clear, a target hub in recovery or shutting down (hand it off again after that ends), and an older target hub (it lacks the `task_handoff` feature: run `ahub upgrade` in that project).
|
|
5468
|
+
|
|
5469
|
+
Recovery: `task_handoff` is its own recovery label. A project that holds a handoff row, in either direction, refuses a recovery target that lacks it.
|
package/docs/profiles.md
CHANGED
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
- Configure an explicit machine-local `checks.fact_check` command if desired. Alias checks take precedence over a base `checks.test`; no check runs merely because a profile was selected.
|
|
22
22
|
- Example deterministic check: `bun /path/to/agent-hub/scripts/check-citations.ts report.md references.bib`. It checks bracketed Markdown `[@key; @other]` keys against BibTeX entry keys, with 256 KiB/4 MiB input caps. It performs no fetch, validates no source quality and is not a full Markdown/BibTeX parser. A missing key exits 1. A resolved bibliography is one check, not proof that claims are supported.
|
|
23
23
|
- Keep a person's sign-off as the final review. The live three-source/two-agent example remains unverified and was not run during solo implementation.
|
|
24
|
+
- A multi-unit study (#930, #601) goes through `ahub study`: the person (or a configured planner with `hub_study_draft` / `hub_study_revise`) stores a contract as a draft, only the person approves it with `ahub study approve <id> <revision>`, which creates one task per unit, and anyone reads coverage with `ahub study show [<id>]` or `hub_study_show`. A unit owner records `hub_study_handoff` with evidence for every source the unit names, or `insufficientEvidence`; a done task is not a handoff, and an incomplete handoff does not close a discovery round. A private campaign, task or source shows ids, counts and states only.
|
|
25
|
+
- The deterministic three-source, two-peer example (`test/study-daemon.test.ts`, "three-source, two-peer example"): one contract names sources S0, S1 and S2 and two discovery units, `alpha` (S0 and S1, owned by codex) and `beta` (S2, an independent check, owned by kimi). After `ahub study approve` both units read `none` and `0/2 covered`, `0/1 covered`. A handoff for S0 only moves `alpha` to `incomplete` with `1/2 covered`. A handoff for both S0 and S1, and one for S2, make both `complete` and the discovery round complete. Another peer's handoff for `alpha` is refused. This runs with fake peers: it shows the hub's rules, not that a native model follows the guidance.
|
|
24
26
|
|
|
25
27
|
# General project example
|
|
26
28
|
|
package/docs/quickstart.md
CHANGED
|
@@ -11,13 +11,13 @@ The registry package uses the `staix` organization scope. Install from npm:
|
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
bun add -g @staix/agent-hub # installs `ahub` (also as `agent-hub`)
|
|
14
|
-
ahub setup # installs the
|
|
14
|
+
ahub setup # installs the channel plugin and a project-neutral hook in each Claude home in use, then runs doctor
|
|
15
15
|
```
|
|
16
16
|
|
|
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.25.0
|
|
21
21
|
ahub setup
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -30,6 +30,18 @@ and upgrade or crash recovery, see the [operations guide](operations.md). To
|
|
|
30
30
|
move running projects to a newer release later, run `ahub upgrade` in a
|
|
31
31
|
terminal: it reviews the plan with you, applies it and follows it.
|
|
32
32
|
|
|
33
|
+
## Upgrading to 0.25.0
|
|
34
|
+
|
|
35
|
+
Nothing changes until you use something new. `ahub setup` now also registers agent-hub as a plugin of the family console ([agent-console](https://github.com/STAIxBWLB/agent-console), `acon ui`): it writes `~/.agenthub/console/plugins/ahub.json` with the sha256 of the installed `@staix/agent-hub/ui-plugin` module, so acon shows the dashboard's views as panels for every running project, lists pending approvals (Allow once / Deny) and in-review tasks whose reviewer is you in its inbox, and asks you to confirm every outward or destructive action first (#935, #1032). The same plugin feeds acon's Space view from the dashboard's office model: peers are actors, the board columns are zones and task links and recent messages are links, with labels and states only, never bodies, details or approval titles (#1012, #1033). acon refuses a module that changed after setup, so run `ahub setup` again after this and every later upgrade. The hub exact-pins `@staix/agent-mem` 0.18.0 (was 0.15.0); since agent-mem 0.16.0 every amem writer on one memory home, hub pins included, must run 0.16.0 or later, because an older drain deletes hook-spool records a newer one staged without reading them, so upgrade the hub together with a global `amem` of 0.16.0 or later (#1035, #1042). `ahub doctor` now reads its `memory capture: codex` and `memory capture: kimi` rows from that `amem` (`amem setup <tool> --json`, a preview that writes nothing) instead of `dot ai memory status`, and names `amem setup <tool> --apply` when setup is pending (#1025). Research campaigns are new and start only when you draft one: `ahub study draft` stores a contract (question, scope, sources, units and a stop policy) as a draft, a configured planner may draft and revise it with `hub_study_draft` and `hub_study_revise`, only your `ahub study approve` creates the unit tasks as Backlog cards for the planner to offer, unit owners record their evidence with `hub_study_handoff`, and `ahub study show` reports coverage per unit, budget support and why dispatch is held; `ahub study approve-protocol` approves one exact experiment protocol hash (#1024, #1027, #1028, #1029, #1031, #1041; see [research campaigns](operations.md#research-campaigns-ahub-study-930)). While campaign or experiment records exist, a restart, upgrade or recovery onto an older release is refused. A schedule in `config.local.json` can now take a five-field `cron` expression with an optional IANA `tz` instead of `every`; while one does, a restart or recovery onto an older release is refused (#1022; see [calendar schedules](operations.md#calendar-schedules-cron-and-tz-1017)). An owner can now re-file `hub_task_done` during review with a different full commit SHA, and the reviewer gets a fresh request for the new head (#1021). Work that belongs to another project that runs agent-hub on this machine can now go onto that project's board: `ahub task handoff --project <root|id> <title...>` (you) or `hub_task_handoff` (a planner or the conductor) files it there as an ownerless proposal when that hub is running and has the `task_handoff` feature, and `ahub board --handoffs` and the requesting agent learn each state change it reaches (#1030, #1043; see [handing work to another project](operations.md#handing-work-to-another-project-604-agent-hub1030)); while a handoff record exists, a restart, upgrade or recovery onto an older release is refused. A connection that names a peer but is not that peer's current Claude session, such as a plugin that inherited another project's hub, now joins as a distinct `<peer>~<id>` sender that can send and read but holds none of that peer's roles, and every message and attach in `events.jsonl` records the sending connection; nothing that connected before is refused, this tells sessions apart without authenticating them, and while an unsettled delivery holds such a session's message, a restart, upgrade or recovery onto an older release is refused (#1036, #1037). Upgrade running hubs with `ahub upgrade` and restart Claude sessions so they load the 0.25.0 plugin.
|
|
36
|
+
|
|
37
|
+
## Upgrading to 0.24.0
|
|
38
|
+
|
|
39
|
+
Nothing changes until you opt in. `ahub autonomy on` (person only, from a terminal) previews the shipped autonomy preset for this project and applies it with one confirmation: task auto-pull and sweep switches, permission and start defaults, and `action_policy.floor: true`. `--all-projects` applies it to every registered project. `ahub autonomy status [--json]` reports each peer's effective mode, where the floor is enforced and the Claude homes. `ahub autonomy off` removes the preset keys, including hand-set values of those keys, and the retained consent (#1009, #1010; see [project autonomy](operations.md#project-autonomy-one-preset-and-one-confirmation-999-t1)). `on` also writes the machine default `~/.agenthub/defaults.json` (owner-only, 0600), which a newly initialized project inherits; `off` disables it (see [machine autonomy](operations.md#machine-autonomy-and-claude-homes-999-t2)).
|
|
40
|
+
|
|
41
|
+
The floor is off by default and set only in untracked `config.local.json`. It lets a push of a literal non-default branch to `origin`, and `gh pr create|comment|review|merge` in the project's own repository, run without asking. Force pushes, default-branch and tag pushes, releases, package publishes and anything the classifier cannot decide still ask. Where the hub does not see a call first, `ahub autonomy status` says the floor is not enforced there (#1007, #1011; see [floor policy](operations.md#floor-policy-ordinary-development-work-does-not-ask-999-t3)). While the preset, retained consent or the floor is set, a restart, upgrade or recovery onto an older release is refused; turn autonomy off first.
|
|
42
|
+
|
|
43
|
+
`ahub setup` now covers every Claude configuration home in use (`CLAUDE_CONFIG_DIR`, the default home and the homes of live registered Claude launches). After one confirmation it installs a project-neutral PreToolUse hook beside the plugin and leaves unrelated hooks and `statusLine` alone (#1010). The hub exact-pins `@staix/agent-mem` 0.15.0, which changes only the `amem` CLI, so memory homes are unchanged (#1015). Claude Code 2.1.316 joins the verified headless implementer versions; 2.1.315 stays unverified (#1014). Upgrade running hubs with `ahub upgrade` and restart Claude sessions so they load the 0.24.0 plugin.
|
|
44
|
+
|
|
33
45
|
## Upgrading to 0.23.1
|
|
34
46
|
|
|
35
47
|
The hub now exact-pins `@staix/agent-mem` 0.14.0, with no storage change for the hub. amem 0.14.0 adds an opt-in v2 public prune view (`amem migrate --public-prune-view`) that 0.13.0 and earlier readers refuse once it is activated: before a person activates it, upgrade every hub that shares the memory home to 0.23.1 or later (which bundles amem 0.14.0) and every global `amem` CLI to 0.14.0. Claude Code 2.1.314 joins the verified headless implementer versions (#996), Kimi Code 2.4.1 the fresh reviewer versions and Qwen Code 0.26.4 the ACP versions (#1002); the Qwen dual-output TUI stays on 0.26.1 and Codex 0.166.0 stays unverified (#997).
|
|
@@ -136,7 +148,7 @@ The restarted Claude planner gets the release-train tools (`hub_release_new`, `h
|
|
|
136
148
|
|
|
137
149
|
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`.
|
|
138
150
|
|
|
139
|
-
Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.
|
|
151
|
+
Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.18.0. Before anyone runs `amem migrate --shards` on a memory home, every hub using that home must run 0.12.37 or later: an older hub does not see the split and keeps writing the old layout. `ahub memory profile-check` is split-aware and compares each hub with its own project's shard (#536). See [memory profiles and rollout](memory.md#selected-memory-profile).
|
|
140
152
|
|
|
141
153
|
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:
|
|
142
154
|
|
|
@@ -204,7 +216,7 @@ More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-de
|
|
|
204
216
|
|
|
205
217
|
## Shared memory
|
|
206
218
|
|
|
207
|
-
The hub exact-pins the first-party `@staix/agent-mem` 0.
|
|
219
|
+
The hub exact-pins the first-party `@staix/agent-mem` 0.18.0 core, including deterministic capture; no claude-mem worker is needed. Existing shared-v1 memory remains the default; upgrading does not migrate it. Managed agents use screened `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools, or propose a correction with `hub_memory_correct`; only a person accepts candidates through the supported `amem review` path. Since agent-mem 0.7.0, `amem review` also accepts candidates on a selected generation.
|
|
208
220
|
|
|
209
221
|
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.
|
|
210
222
|
|
|
@@ -237,6 +249,9 @@ load historical logs. An unopened dashboard has no listener. A paused budget
|
|
|
237
249
|
window cannot be overridden on the page; the CLI's `ahub budget resume <peer>`
|
|
238
250
|
remains the explicit override.
|
|
239
251
|
|
|
252
|
+
If you use the family console (`acon ui`), `ahub setup` registers the same
|
|
253
|
+
dashboard there as a plugin; see [the acon console plugin](operations.md#acon-console-plugin-935-1012).
|
|
254
|
+
|
|
240
255
|
|
|
241
256
|
## Concurrent project development (0.4.0)
|
|
242
257
|
|