@staix/agent-hub 0.30.0 → 0.31.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 +39 -0
- package/README.md +13 -7
- package/docs/agent-notes/README.md +1 -0
- package/docs/agent-notes/adapters.md +5 -2
- package/docs/agent-notes/budget.md +1 -0
- package/docs/agent-notes/bus.md +9 -4
- package/docs/agent-notes/daemon.md +15 -8
- package/docs/agent-notes/local-worker.md +1 -0
- package/docs/agent-notes/tasks.md +7 -3
- package/docs/agent-notes/tests.md +6 -4
- package/docs/design/adapters.md +52 -0
- package/docs/design/agent-hub-architecture.md +46 -0
- package/docs/design/bus.md +139 -1
- package/docs/design/task-board.md +82 -0
- package/docs/dogfood.md +22 -4
- package/docs/events.md +3 -0
- package/docs/memory.md +17 -1
- package/docs/operations.md +307 -78
- package/docs/profiles.md +35 -0
- package/docs/quickstart.md +18 -5
- package/docs/security.md +154 -60
- package/docs/specs/2026-09-19-agent-hub-design.md +84 -14
- package/docs/specs/2026-09-19-multi-project-design.md +7 -2
- package/docs/verification/2026-11-04-1171-channel-client-evidence.md +31 -0
- package/docs/verification/2026-11-05-0.31.0.md +182 -0
- package/docs/verification/2026-11-05-claude-implementer-2.1.318.md +70 -0
- package/docs/verification/2026-11-05-hardcoded-values-classification-rules.md +257 -0
- package/docs/verification/2026-11-05-hardcoded-values-ratchet.md +55 -0
- package/docs/verification/2026-11-06-rooms-presence-cost.md +152 -0
- package/docs/verification/claude-shell-wrapper-native.py +1 -1
- package/docs/verified.json +14 -14
- package/package.json +3 -4
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +4393 -3609
- package/src/adapters/acp.ts +5 -4
- package/src/adapters/channel-peer.ts +72 -3
- package/src/adapters/claude-channel-evidence.ts +52 -0
- package/src/adapters/claude-channel.ts +61 -18
- package/src/adapters/claude-implementer.ts +29 -7
- package/src/adapters/claude-print-child.ts +12 -2
- package/src/adapters/codex-appserver.ts +13 -12
- package/src/adapters/compat.ts +3 -3
- package/src/adapters/definitions/builtin-metadata.ts +13 -13
- package/src/adapters/definitions/qwen.ts +1 -0
- package/src/adapters/local-worker.ts +61 -18
- package/src/adapters/pi.ts +48 -6
- package/src/adapters/registry-types.ts +12 -0
- package/src/adapters/registry.ts +2 -0
- package/src/adapters/reviewer-print.ts +50 -11
- package/src/broker/server.ts +44 -13
- package/src/broker/store.ts +38 -8
- package/src/cli/answer-args.ts +50 -0
- package/src/cli/attention.ts +17 -2
- package/src/cli/backlog-return-args.ts +37 -0
- package/src/cli/console-question.ts +110 -0
- package/src/cli/console-state.ts +77 -16
- package/src/cli/console.ts +54 -1
- package/src/cli/handoff-args.ts +15 -5
- package/src/cli/handoff-output.ts +15 -2
- package/src/cli/help.ts +8 -5
- package/src/cli/identity.ts +13 -3
- package/src/cli/main.ts +128 -16
- package/src/cli/memory.ts +107 -3
- package/src/cli/output.ts +29 -6
- package/src/cli/pet.ts +4 -4
- package/src/cli/results-args.ts +30 -0
- package/src/cli/runtime-version-warning.ts +50 -0
- package/src/cli/status-lines.ts +41 -1
- package/src/cli/tail-render.ts +1 -0
- package/src/cli/upgrade-interactive.ts +14 -2
- package/src/hub/action-class.ts +9 -1
- package/src/hub/board.ts +369 -18
- package/src/hub/bus.ts +493 -53
- package/src/hub/completion-detail.ts +50 -0
- package/src/hub/completions-store.ts +168 -0
- package/src/hub/completions.ts +120 -0
- package/src/hub/config-apply.ts +7 -5
- package/src/hub/config-reload.ts +10 -1
- package/src/hub/control-client.ts +40 -4
- package/src/hub/daemon.ts +1569 -134
- package/src/hub/delivery-failure.ts +14 -0
- package/src/hub/delivery-hints.ts +14 -4
- package/src/hub/delivery-journal.ts +751 -42
- package/src/hub/delivery-superseded.ts +4 -1
- package/src/hub/envelope.ts +3 -3
- package/src/hub/events.ts +6 -0
- package/src/hub/handoff.ts +145 -6
- package/src/hub/hub-tools.ts +56 -7
- package/src/hub/manager.ts +59 -3
- package/src/hub/memory-policy.ts +44 -1
- package/src/hub/memory-sync-policy.ts +109 -0
- package/src/hub/memory-sync-state.ts +145 -0
- package/src/hub/no-writes.ts +1 -1
- package/src/hub/operational-settings.ts +11 -2
- package/src/hub/operational-view.ts +12 -1
- package/src/hub/peers.ts +25 -2
- package/src/hub/planning.ts +6 -1
- package/src/hub/question-desk.ts +201 -0
- package/src/hub/question-detach.ts +6 -0
- package/src/hub/questions.ts +260 -0
- package/src/hub/research-evidence.ts +106 -0
- package/src/hub/restart.ts +14 -0
- package/src/hub/review-anchor.ts +181 -0
- package/src/hub/review-brief.ts +13 -0
- package/src/hub/review-comments.ts +115 -0
- package/src/hub/review-findings.ts +7 -2
- package/src/hub/review-material.ts +76 -0
- package/src/hub/routing.ts +3 -1
- package/src/hub/task-sweep.ts +2 -0
- package/src/hub/tasks.ts +577 -63
- package/src/memory/capture.ts +5 -2
- package/src/pet/config.ts +25 -13
- package/src/rooms/link.ts +209 -21
- package/src/rooms/remote-peer.ts +186 -19
- package/src/rooms/service.ts +338 -22
- package/src/rooms/store.ts +437 -65
- package/src/rooms/wire.ts +24 -6
- package/src/ui/index.html +138 -7
- package/src/ui/needs.ts +10 -4
- package/src/ui/plugin-questions.ts +56 -0
- package/src/ui/plugin-results.ts +81 -0
- package/src/ui/plugin.ts +207 -27
- package/src/pet/window.html +0 -114
- package/src/pet/window.jxa.js +0 -122
- package/src/pet/window.ts +0 -154
|
@@ -30,6 +30,9 @@ paths:
|
|
|
30
30
|
- src/hub/task-repository.ts
|
|
31
31
|
- src/hub/no-writes.ts
|
|
32
32
|
- src/hub/review-findings.ts
|
|
33
|
+
- src/hub/review-anchor.ts
|
|
34
|
+
- src/hub/review-comments.ts
|
|
35
|
+
- src/hub/review-material.ts
|
|
33
36
|
- src/hub/workflow.ts
|
|
34
37
|
- src/hub/deliverables.ts
|
|
35
38
|
- src/hub/deliverable-files.ts
|
|
@@ -39,6 +42,7 @@ paths:
|
|
|
39
42
|
- src/hub/ci-watch.ts
|
|
40
43
|
- src/hub/research-campaign.ts
|
|
41
44
|
- src/hub/research-experiments.ts
|
|
45
|
+
- src/hub/research-evidence.ts
|
|
42
46
|
- src/hub/research-runner.ts
|
|
43
47
|
- src/hub/task-approval.ts
|
|
44
48
|
- src/hub/schedules.ts
|
|
@@ -87,6 +91,70 @@ Review independence and declared scope are different controls. Selection exclude
|
|
|
87
91
|
|
|
88
92
|
Task text and private-turn words can reach owners, reviewers, overlap notices and memory. Public views use the host's current privacy projection; PII tasks remain stubs for unauthorized observers, and private turns cannot write ordinary shared task text. The projection belongs at the shared boundary because filtering individual callers would leave another observer exposed ([#198](https://github.com/STAIxBWLB/agent-hub/issues/198), [#230](https://github.com/STAIxBWLB/agent-hub/issues/230)).
|
|
89
93
|
|
|
94
|
+
## Claim evidence records (#931 T1)
|
|
95
|
+
|
|
96
|
+
The #901 owner boundary exposes one canonical `taskClaimIdentity(task, slot)`.
|
|
97
|
+
`claimId` is `claim:<task id>:<created>:<1-based slot>`, so a reset that reuses a
|
|
98
|
+
task number cannot inherit an earlier task's evidence. `claimRevision` is the
|
|
99
|
+
existing `claimListId(task.plan?.claims)`, the opaque 16-hex ordered-list hash
|
|
100
|
+
already stamped in person verdicts. `recordClaimVerdict` and the evidence writer
|
|
101
|
+
use that same helper; neither a second claim/verdict store nor a numeric claim
|
|
102
|
+
counter is introduced. Exact-list restoration retains #901's existing verdict
|
|
103
|
+
semantics. The list-level ceiling is conservative: any claim edit, reorder or
|
|
104
|
+
replacement stales every link bound to the changed list. Per-claim revisions
|
|
105
|
+
would be the upgrade path if that over-invalidation becomes a problem.
|
|
106
|
+
|
|
107
|
+
Existing `hub_task_show` and `ahub task show --json` views expose a research
|
|
108
|
+
task's current text-free `claims: [{slot, claimId, claimRevision}]` bindings,
|
|
109
|
+
derived only from that canonical helper. PII tasks expose none, and dev views
|
|
110
|
+
keep their existing shape. A caller copies the returned binding rather than
|
|
111
|
+
reimplementing plan hashing; a changed list requires a fresh view before record.
|
|
112
|
+
|
|
113
|
+
`EvidenceLinkV1` carries exactly `id`, `claimId`, `claimRevision`, `sourceId`,
|
|
114
|
+
`rawSha256`, `projectionSha256`, `projectionVersion`, `locator`, `relation`,
|
|
115
|
+
`recordedBy`, `taskId` and `revision`. Relations are `supports`, `contradicts` or
|
|
116
|
+
`context`, all declared provenance rather than an entailment decision. `locator`
|
|
117
|
+
stores proposed zero-based, half-open Unicode scalar-value `start`/`end` bounds
|
|
118
|
+
with a nonempty span of at most 4096. T1 does not convert offsets, resolve text,
|
|
119
|
+
accept page/section/excerpt fields or claim a projection is verified.
|
|
120
|
+
|
|
121
|
+
The flat `hub_evidence_record` input omits host-owned `recordedBy`; `revision`
|
|
122
|
+
defaults to 1 and `id` is optional for initial writes. A later revision names
|
|
123
|
+
its existing ID and the next revision number. Initial IDs are deterministic for
|
|
124
|
+
the same normalized input and actor. Replaying identical canonical bytes at an
|
|
125
|
+
existing ID/revision writes nothing; conflicting bytes or an out-of-sequence
|
|
126
|
+
revision refuse. Every accepted revision remains in the append-only evidence
|
|
127
|
+
table. #901 person-verdict history and scorecard counts remain the sole judgment
|
|
128
|
+
record, unaffected by evidence relation labels.
|
|
129
|
+
|
|
130
|
+
Tasks prechecks sequence and claim association before screening and immediately
|
|
131
|
+
before append; the Board transaction repeats them as the race fence. Ordinary
|
|
132
|
+
sequence/association refusals are pre-effect and name the expected next revision
|
|
133
|
+
when applicable. Invalid stored evidence directs the person to stop the hub,
|
|
134
|
+
restore a trusted project `hub.db` backup, restart and retry; T1 does not name an
|
|
135
|
+
unimplemented evidence-read command.
|
|
136
|
+
|
|
137
|
+
`Tasks.evidenceRecord` admits only the current in-progress owner of a stored
|
|
138
|
+
research-profile task, with current claim binding and registered source/raw hash.
|
|
139
|
+
Standalone tasks do not need a campaign, and role-catalog guidance grants no
|
|
140
|
+
authority. Recovery/shutdown holds, private turns, PII tasks, private sources,
|
|
141
|
+
unknown sources, stale claims and foreign-task writes refuse before effects.
|
|
142
|
+
Every awaited preparation is followed by current task/source/actor checks; the
|
|
143
|
+
append transaction also fences task incarnation, owner, flow and claim revision.
|
|
144
|
+
Current metadata privacy is checked again after asynchronous screening and immediately before append; a failed or unavailable policy refuses. Successful evidence receipts, including replay, are owner task effects for the existing no-write advisory.
|
|
145
|
+
Public receipts contain only link ID, revision and task ID. The tool is excluded
|
|
146
|
+
from argument/result capture and from read-only publication; dev-profile tool
|
|
147
|
+
lists retain their existing shape.
|
|
148
|
+
|
|
149
|
+
Projection hashes/version are caller-declared T1 bindings; only the raw source
|
|
150
|
+
hash is checked against registry metadata. Locator resolution, Unicode offset
|
|
151
|
+
conversion and current-privacy public revalidation are T2. Evidence read/CLI
|
|
152
|
+
surfaces, complete inventory bindings and synthesis readiness remain later work.
|
|
153
|
+
Stored evidence adds a conditional `research_evidence` recovery feature and
|
|
154
|
+
`{links, revisions, digest}` integrity section. An absent section is the empty
|
|
155
|
+
store, preserving older recovery records; an empty database requires no new
|
|
156
|
+
feature. Provenance never manufactures a person verdict or readiness result.
|
|
157
|
+
|
|
90
158
|
## Read models and policy extensions
|
|
91
159
|
|
|
92
160
|
Agent list reads return bounded, newest-updated compact pages built from public rows, with a keyset cursor and explicit detail/ID reads. Console compatibility is separate. Pagination is not a frozen snapshot during concurrent edits; its purpose is bounded communication without bypassing private-row projection ([#1083](https://github.com/STAIxBWLB/agent-hub/issues/1083)).
|
|
@@ -102,3 +170,17 @@ The board stores facts about worktrees and never a verdict. `worktree_override`
|
|
|
102
170
|
The PR state has two sources and no others. The board's own evidence says `merged` only through the guarded merge's record (`sdlc.merge`); a cancelled task or a task with no record says nothing about its PR and reads `unknown`. The person's explicit refresh (`worktrees_refresh_prs`, `src/hub/worktree-prs.ts`) reads the PR through `readSdlcPr`, bounded and one at a time, and keeps `open`, `merged` or `closed` with GitHub's own change time in the daemon's memory. `worktree-shelf.ts` holds no GitHub access, so a panel read, `ahub worktrees` and the inbox alert make no GitHub call.
|
|
103
171
|
|
|
104
172
|
A worktree whose activity could not be read is live and never settled. The shelf reads git asynchronously under a total budget and answers `complete: false` when it is cut; the daemon's event loop is never held. The daemon deletes no worktree and no local branch: its git port allows three read argv shapes, and removal exists only in the person's own `ahub worktrees tidy --confirm`, which is console class and issues `git worktree remove` and `git branch -d`, never `--force` or `-D`. Operations: `docs/operations.md`, "The worktree shelf (#1057)".
|
|
173
|
+
|
|
174
|
+
## Anchored review packages (#1056)
|
|
175
|
+
|
|
176
|
+
`ReviewFinding.anchor` uses the exact-pinned `@staix/agent-console` 0.1.3 DOM-free `./contract` entry through type-only imports. The generated declaration bridge is removed. `test/acon-review-contract.test.ts` checks the unchanged shared fixtures against both the published acon conformance functions and the hub validator; the project retains its Bun-only TypeScript libraries. Contract conformance and hub writes are separate: hub writes allow 1-4 selectors, 512 UTF-8 bytes for an exact quote, 64 each for prefix and suffix, 256 for a hunk header, 2048 for a comment body and 64 comments per task. The hub additionally caps paths at 4096 bytes, projection name/version and structural scheme at 128 each, structural ref at 512 and verified author identity at 512. These bounds keep each stored thread within its fixed read bound. Quote selector text remains exact in storage; `sanitize()` applies when it is rendered beside hub headers. The hub limits count UTF-8 bytes, independently of acon's character limits: 171 Hangul syllables exceed the 512-byte exact-quote cap. Refusals identify the field, bound and next step. Unknown fields and selectors refuse before effects. A finding path, when present, must equal its anchor path. Findings without anchors retain the existing head buckets and Important carry-over rule.
|
|
177
|
+
|
|
178
|
+
All person comment writes go through `Tasks`. The console can put or delete a draft without a peer envelope. An explicit send binds the selected immutable anchors and bodies to one package, changes their lifecycle to sent, appends one count-only task history entry and attempts one review envelope. A failed or uncertain notification never retries automatically. Its receipt distinguishes queued from unconfirmed delivery; neither means the owner read it. The saved package retains its immutable body, envelope identity, original visibility binding and versioned publication-evidence contract. Its serialized record must fit 32768 UTF-8 bytes before any sent write. A previously unpublished package is admitted only while every selected comment remains sent and its originally visible text remains public under current policy; a missing binding, dismissal or privacy change refuses without rewriting or publishing the old body. An explicit confirmed Send with `packageId` recovers only that saved package. Durable queue or delivery evidence makes this idempotent, including after restart; failed or discarded deliveries refuse with their actual state and `ahub queue` inspection guidance rather than reporting queued or replaying the effect. Unknown evidence and legacy packages refuse with inspection guidance. Person-package terminal receipts are retained alongside the package rather than pruned with ordinary delivery history. Quote-bearing reviewer requests use a distinct `reviewer-request-` marker and their terminal rows follow ordinary pruning. This retains a full receipt per package; package archival with an IDs-only tombstone is the upgrade path. Deleting a sent comment dismisses it without rewriting its anchor. Only a final successful owner completion may claim resolved comment IDs; a queued or failed check leaves them sent. That claim is not person verification or a review verdict.
|
|
179
|
+
|
|
180
|
+
The actor is the console person, not a conductor or a peer. acon authorship comes only from the server-built `ActionMeta` argument. Client body fields cannot supply an author, timestamp or authority. The standalone dashboard is read-only; acon's shared `ui.review` kit owns selection and Send. Older acon hosts without the kit retain the read-only view.
|
|
181
|
+
|
|
182
|
+
Placement is computed before reads and sends, never persisted over the stored anchor. Equal content hashes are anchored; a different hash with a uniquely matching exact quote is moved, with context breaking ties; unresolved changes are outdated. Missing, denied, private or over-budget material is unavailable. Projection identity mismatches are outdated before hash comparison. A display range from moved placement never becomes a new stored selector. An unavailable public comment retains its stored thread in the person view, labelled unavailable. Send refuses before any effect and names each unavailable selected comment. Actual PII/private comments remain count-only. Carried finding placement belongs to one asynchronous review admission. Rare synchronous role re-offers without that material report unavailable until the next refresh, rather than reusing old coordinates.
|
|
183
|
+
|
|
184
|
+
Periodic dashboard snapshots perform no comment-material Git or GitHub reads. Explicit task open or refresh requests the review section; a failed read marks only that section unavailable. Material uses the recorded task head and never substitutes the worktree HEAD for a missing commit. Material comes only from guarded immutable Git snapshots in the task's declared refs, plan paths or sections, or complete same-head verified PR paths. Every operation shares eight distinct files, eight seconds including head/PR preparation and 12000 serialized presentation bytes. Both sides share the budget. Truncated material cannot establish placement. Raw hashes bind bytes; projected hashes bind only UTF-8 projected text. The projection name is `text-projection:<extension>` and its version is the existing configured converter fingerprint. This is an opaque configuration identity, not an upstream semantic version; a converter version protocol would be the upgrade path.
|
|
185
|
+
|
|
186
|
+
PII comments remain board-local and public views expose counts only. Private paths retain only supplied lineRange or structural selectors; no coordinate is invented when unsafe selectors are removed. Public review packets carry a host-only opaque package marker so their intended owner receives the packet while logs, operational tails, incoming labels, capture and memory observers receive no quote or body. This marker does not turn an ordinary task into a PII turn. Structured anchored verdicts retain the GitHub verdict mirror with a verdict-only headline when quote provenance is present. Decision metadata, contradiction and safe recurring criteria retain their existing paths; quote-bearing finding proposals remain excluded. The configured PII screen checks reviewer prose before owner-facing publication without receiving source quote selectors. Durable open sent comments and outstanding anchored findings bind shared-memory admission only to the task a note names and its recipient, across restart and intervening chat. Sent comments hold those task-bound writes until resolution or person dismissal; resolved or dismissed comments alone do not retain reviewer history scope. They do not hold notes for an unrelated task or an untagged note after ordinary new input. Anchored-finding scope is conservatively held until the task closes, including later fixed dispositions; a persisted review-package epoch is the path to narrower closure. The metadata scope read is cached against database change stamps and fails closed above 500 role tasks or 16 MiB of UTF-8 history. This exclusion does not hide the owner's summary or check output from its reviewer or owner. Review requests retain trusted observer provenance whenever historical anchors or non-draft comments can be reflected in the completion text, including after comment resolution. Current input provenance separately holds all shared-memory writes and observer sinks for an actually delivered quote-bearing review input or a newly submitted anchored verdict, even if the verdict is refused or immediately closes the task. This exclusion is latched for the input turn until a permitted ordinary next-turn handoff replaces it; restored pull-only sessions instead require a changed native identity. Resolving comments or ending the task alone does not clear it. Bounded ID-only journal receipts preserve held session/input provenance across daemon restart. No matching held record in a complete, intact and readable store is clean; missing expected prior-session records and unreadable, corrupt or unconfirmed session coverage remain unknown. A validated matching release receipt confirms only its own identity. Restored pull-only sessions retain their hold until the native identity changes, regardless of inbox handout. An empty in-memory map alone is not replacement proof. Presence-only traffic and additional inputs within the same active turn cannot clear a latched exclusion. Committed inbox handouts carry the same current-input provenance as push input without claiming a native ACK. Local-worker batches latch before executing any tool, and their final answer and retained history obey the same exclusion. Owner-addressed review outcomes cannot be automatically settled merely because task or reviewer state moved. Original saved-package recipients retain comment scope while comments remain sent, and queued/deferred or unsettled delivery records retain their actual recipients independently of current task roles. A comment dismissal is not a delivery-consumption receipt; any separate uncertainty hold requires explicit disposition. Recovery treats an absent comment section as empty and checks the optional section's counts and digest when present.
|
package/docs/dogfood.md
CHANGED
|
@@ -11,14 +11,19 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
11
11
|
| Feature | State here | Measured by |
|
|
12
12
|
| --- | --- | --- |
|
|
13
13
|
| Distinguishable sessions and sender provenance (#1036, `session_identity`) | on after release and upgrade: a connection that names a peer id but is not that peer's current session is a distinct `<peer>~<origin>` session that can send and read, holds none of the peer's roles and replaces nobody; the channel plugin binds to its own project; every envelope and attach event records the connection. Nothing is refused to a connection that worked before. The recovery label `session_identity` applies once an unsettled delivery holds a session's message | `grep '"session":true' .agenthub/state/events.jsonl` lists every message a foreign session sent, with its minted id and no path or text; a recipient's header shows `from "claude~<id>"` for it; test/identity-provenance.test.ts (AC1, AC3, AC4, recovery label) and test/identity-channel-project.test.ts (AC2, real plugin against a new and an old hub) hold it. Not authentication: a same-user process can always act as the user |
|
|
14
|
-
|
|
|
15
|
-
|
|
|
14
|
+
| Claude channel attach evidence (#1171) | source and fixture coverage after merge and plugin/daemon upgrade; native Claude push proof remains unverified until a live `ahub claude` session | `ahub status` shows `channel` or `tools-only` with its evidence label; a marker-inheriting non-channel parent remains pull-only and its delivery is read by `hub_inbox` (`test/claude-channel-evidence.test.ts`, `test/daemon.test.ts`); inspect native TUI attaches separately, since fixtures use a synthetic parent row |
|
|
15
|
+
| Accepted channel delivery settlement (#1172) | source and fixture coverage after merge and plugin/daemon upgrade; native channel handling and long-running-session behavior remain unverified | `bus.accepted_settle_ms` defaults to 10 minutes; explicit channel `hub_inbox` metadata shows accepted/held ids and revisions even when a pull is blocked; a timeout becomes `needs_review` without replay; an important/task/review timeout yields one ids-only status notice when the configured conductor feed is on, with `feed: off` remaining an opt-out; daemon and MCP fixtures cover timeout and opt-out; live accepted-to-completed/timeout behavior remains unverified |
|
|
16
|
+
| Cross-project task handoff with state follow-back (#604, `task_handoff`) | on after release and upgrade: `ahub task handoff` and `hub_task_handoff` register work for another registered project that runs agent-hub on this machine as an ownerless proposal on its board; the requesting peer is told each state change as a `kind: task` message. Nothing is queued, and the origin has no authority there | `ahub board --handoffs` lists what this project handed over with the last state each target reported; `ahub board` and `ahub task show` in the target name the origin project and peer; a handoff for a spec issue that already has an open task there is refused with the task ids unless `duplicate_ok` gives a reason, and the receiving conductor can cancel an unaccepted handoff (#1175; the share of refused handoffs and the cancels the person no longer has to run show whether duplicates still reach the board); a handoff the target did not confirm (a timeout, #1203 T1) is reported as `outcome_unknown` with a key and a retry with `--key` files it once, and a follow-back names the target's task (`refs.handoff`) so a local task of the same number cannot drop it (count `outcome_unknown` refusals, and any target task filed twice for one origin: there should be none; from T2 (#733) the origin also asks every 5 minutes and when a target restarts, so a missed notify arrives within a period: compare how long a handoff row stays behind its target (its `updated` against the target's state), and count `changes requested` and `reopened` messages, which used to be silent; from T3 (#734) `ahub task handoff --list` shows each handoff's age and whether its target is reachable, unreachable (with the cause) or moved, `--sync` asks the targets now, a wire-version refusal is `older_target` and an instance mismatch is `mismatch` instead of "not running", and a failed notify or catch-up logs one line per target and cause per 15 minutes: count the `handoff catch-up of ... failed` and `... skipped` lines in `hub.log` by cause, how often `--list` shows a target unreachable or moved for more than a day, and whether `--sync` is ever needed after a restart (it should not be: the catch-up reads the state within a period); T1 and T2 and T3 of #1203 are now all built; test/handoff-daemon.test.ts runs two real daemons (AC1 to AC5, #1175, the recovery label and #1203 T1 AC1 and AC4, T2 AC2, AC3 and AC5, T3 AC6 and AC7), test/handoff-core.test.ts and test/handoff-board.test.ts hold the pure core and the tables |
|
|
17
|
+
| Staged project upgrades (#1039) | off: available for the person to upgrade projects independently; this development hub is not upgraded by a fixture | test/published-protocol-compat.test.ts uses both the published 0.25.0 protocol-floor and 0.29.0 release N-1 clients/plugins and reverse daemons; test/staged-upgrade.test.ts checks independent holds and scoped effects; test/staged-runtime-daemon.test.ts checks a real release-root daemon after mutable install removal; test/board-schema-guard.test.ts checks named pre-effect refusal and WAL metadata; `test/project-runtime.test.ts` and `test/project-runtime-lifecycle.test.ts` cover updated resolver retention/refusal and real lifecycle/dashboard routing with synthetic captured daemons; `test/runtime-capture-prune.test.ts` covers references, bounded retention and publication races; `test/upgrade-stopped-project.test.ts` verifies no preservation for stopped projects. These fixtures do not prove published pre-0.26 CLI behavior |
|
|
16
18
|
| Approval head binding and re-review (#1047, #1121) | source/fixture coverage; the #1121 stale-head protections and actionable refusals await release and upgrade; live re-file verification not run | `test/review-head-binding.test.ts` covers both-head refusals, moved-PR commitless re-files and omitted-head stale approvals; `test/task-review-refile.test.ts` covers owner re-submit, reviewer withdrawal, legacy verdict heads, merged/cancelled refusals and held-screen races; `test/sdlc-queue.test.ts` and `test/sdlc-merge.test.ts` reject stale approval at queue and dispatch. `ahub task show <id> --json` exposes `approval.head`, `latestHead`, `mismatch` and `current`; verdict history retains `reviewedHead` |
|
|
17
19
|
| Default agent set started by `ahub up` (#608, `start.agents`) | off here: this repository's agents are started by their own terminals; it is a machine-local setting and a committed config cannot turn it on. On for a person who runs `ahub setup` and `ahub up` on a project that lists agents. | each `ahub up` prints one line per agent (started, already attached, or the refusal with the manual command); the `peer_start` replies in `hub.log` and the terminal provider's recorded starts show whether a listed agent attached, and `ahub status` shows its state after |
|
|
18
20
|
| `ahub down` (counterpart of `ahub up`) | on: an alias of `ahub kill` for stopping this project's hub | the person stops the hub with `ahub down` and `ahub status` then reports it stopped; test/identity.test.ts keeps it person-only (`console`) and labelled `down`, and test/help.test.ts holds its help entry |
|
|
21
|
+
| Person takeover of a channel peer (#1174) | source and isolated fake-session coverage; active after release and plugin upgrade; no live handover receipt yet | one explicit takeover request, old next-tool person-detachment cause, standby attachment identity, no process stop or automatic delivery replay; fake CLI/console authority and stale-generation regressions |
|
|
19
22
|
| Encrypted rooms (#446 X1) | off; source-only crypto/wire, with no broker, room link, invitation CLI or delivery enabled | real WebCrypto vectors and negative wire fixtures; atomic memory fake ports establish ordering only; durable X3 state and the X7 two-machine person receipt remain unverified |
|
|
20
23
|
| Blind room broker (#446 X2) | off; standalone source/fixture work, no public TLS service or hub room link configured here | fake-client auth/fan-out/revocation/restart, ciphertext-only child-process canary, owner admission/offline room reset, queue caps/TTL/FIFO/migration, safe directory modes, and person-only CLI tests; live proxy/account/X7 receipts remain unverified |
|
|
21
|
-
| Room membership and presence (#446 X3) | off; no person room enrollment or exposure configured here | isolated fake-hub/broker tests for OOB enrollment, MITM refusal, durable sequence/replay/grace, explicit fingerprint confirmation/abort, refused-frame retirement, exposure revocation and ids-only presence; room list/status for ids and link state; X4 chat and X7 two-machine live receipt remain separate and unverified |
|
|
24
|
+
| Room membership and presence (#446 X3) | off; no person room enrollment or exposure configured here | isolated fake-hub/broker tests for OOB enrollment, MITM refusal, durable sequence/replay/grace, explicit fingerprint confirmation/abort, refused-frame retirement, exposure revocation and ids-only presence; room list/status for ids and link state; #1204 T1 fixtures cover unchanged-presence dedupe, 1,000 flips with an offline member, latest-only ephemeral broker retention, old-broker wire fallback and same-frame queue_full backoff; CI task 742 adds counter-bounded deferred-presence reuse, concurrent chat ciphertext/Store FIFO and post-close publication regressions (test/rooms-presence-coalescing-742.test.ts, test/bus-closed-publication-742.test.ts); Linux diagnostic counts and targeted hosted macOS acceptance (unchanged AC1 787.72 ms; controlled idle-entry 783.51 ms) are in docs/verification/2026-11-06-rooms-presence-cost.md; no live rooms receipt; X4 chat and X7 two-machine live receipt remain separate and unverified |
|
|
25
|
+
| Presence publication cost (#1204, #740) | source and isolated broker coverage; installed rooms remain off here | unchanged 1,000-flip AC1 test under its 20 s guard; transient pause/resume journal-write count, explicit manual-pause persistence, requestReply and exposure fences; hosted macOS is the acceptance gate |
|
|
26
|
+
| Room automatic resend and late settlement (#1204 T2) | off here; source and isolated in-process broker coverage after validation; release and person enrollment/exposure required; live two-machine behavior remains unverified | AC2-AC4: receiver offline for 15 minutes then each application admitted once; pre-enqueue refusal retries without uncertainty; ACK deadline resends within the original TTL; signed late receipt settles once; local receipt commit survives restart before broker storage; no person-disposition override or native/task-read evidence |
|
|
22
27
|
| Worktree shelf (#1057): `ahub worktrees`, `tidy`, `tidy --confirm <fingerprint>`, the Agents panel section, Park/Pin, the explicit PR refresh and the inbox alert | fixture-only until a person uses it, and only after release and upgrade: this repository keeps every task in `.worktrees/<name>`, so it is the first real use, but nothing here has run `tidy --confirm` yet, and `worktrees.quiet_days` stays 7 until the owner has used it for a week | `ahub worktrees` live and settled counts over a week, and how many settled rows a person then Pins (a Pin means a rule was wrong); `tidy` preview refusals by reason (`task not approved or cancelled`, `unpushed commits`, `branch changed since preview`); after a confirm, `git worktree list` against the preview; test/worktree-shelf.test.ts, test/worktree-tidy.test.ts and test/worktree-panel.test.ts (a PII row stays live and redacted, a branch switch refuses, no GitHub call on a read, the daemon removes nothing) |
|
|
23
28
|
| Message bus, digests, priorities | on | `ahub report`: messages, digests, overflow, undeliverable; delivery latency from events |
|
|
24
29
|
| Control-send recipient normalization (#963) | active after release and hub upgrade; this PR does not change the running hub | string recipients reach only the named peer, invalid shapes publish nothing, omitted/empty arrays preserve broadcast; real native recipient behavior remains unverified |
|
|
@@ -45,7 +50,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
45
50
|
| `ahub deliverables` and the dashboard badge (#509b) | on after the release: `ahub deliverables [--check]` on this repository's board; only tasks that named deliverables appear, so it lists document-shaped work only | the person runs `ahub deliverables --check` after a document task is approved and the next time its file is edited: a `changed since review` row names the edit; `Deliverables n` chips on cards; `not measured now` in the sheet means nobody ran `--check` since the daemon started |
|
|
46
51
|
| Roles per kind and form (#525-1, #525-3, #525-4, #525-5) | on: claude holds the implementer role in the project checkout; isolated terminal and headless Claude implementer support is on, but neither form is declared here | tasks by owner; verified owner isolation and execution-root refusals; headless task-session resumes, inbox task-session refusals, fresh notices and person approval outcomes; missing or mismatched root must never admit a write owner |
|
|
47
52
|
| Codex planner sandbox and role visibility (#525-6) | source/fixture coverage after merge and release; six declared planner/implementer/reviewer instances are not configured here, and the person live leg is unverified | fake thread-start/resume read-only confirmation and refusal before adoption; planner-only Claude mutating-tool grants withheld; status form/capable roles/isolation and task planner/holder-reason parity across CLI, console, dashboard and explain; the native six-instance receipt in `docs/smoke.md` is recorded separately when run |
|
|
48
|
-
| Floor policy (#999 T3, `action_policy.floor`) | source and test after merge and release; off here (a person turns it on in the untracked `config.local.json`), and the running hub takes it after upgrade | `test/action-floor.test.ts` (every allowed, asked and opaque case, status guard rows) and `test/daemon-action-floor.test.ts` (the Pi permit path through the real daemon: allowed calls run with no prompt, force and default-branch pushes, tags, `gh release`, `--admin` and other repositories ask); T4's live receipt records it under Orca |
|
|
53
|
+
| Floor policy (#999 T3, `action_policy.floor`) | source and test after merge and release; off here (a person turns it on in the untracked `config.local.json`), and the running hub takes it after upgrade | `test/action-floor.test.ts` (every allowed, asked and opaque case, status guard rows) and `test/daemon-action-floor.test.ts` (the Pi permit path through the real daemon: allowed calls run with no prompt, force and default-branch pushes, tags, `gh release`, `--admin` and other repositories ask); T4's live receipt records it under Orca. `2>/dev/null`-style redirects to `/dev/null` and `/dev/tty` no longer classify as destroy (#725, #1193; `/dev/stdout`, `/dev/stderr` and `/dev/fd/<n>` stay destroys because on Linux they reopen and truncate the file fd 1 or 2 already points at): active after release and plugin upgrade, unverified in a live agent-research session; the metric is the count of `always-ask: destroy` prompts on commands that only redirect to `/dev/null` or `/dev/tty`, which should reach zero, and `test/action-class.test.ts` (the `#725 device redirect` rows, including the four aliases, `/dev/fd/3` and lookalikes) |
|
|
49
54
|
| Confirmation-point inventory (#999 T0) | source and test coverage; `ahub autonomy status` reads the inventory after this feature is released, with no default prompt change from the data alone | `test/confirmation-matrix.test.ts`: every adapter-catalog kind has a tool-approval and a classed-action row per environment, kinds facts equal the definitions, cited source lines exist; the `unknown` rows are the list T4's live receipt must close |
|
|
50
55
|
| Project autonomy preset (#999 T1) | off on this repository until released and explicitly enabled by the person; project scope only | focused person-only, retained-consent, metadata-independent off and authenticated/fallback preset undo tests; the preset writes `action_policy.floor` (#999 T3) and off removes it; status leads with a peer table separating current modes from desired defaults, groups identical floor verdicts and unknowns once with peer lists (#1137), and reads each floor class from the host verdict (`floorEnforcement`), naming the unverified guard where the hub does not see the call first; the Orca zero-prompt native task remains T4 |
|
|
51
56
|
| Machine autonomy and used Claude homes (#999 T2) | off until released and explicitly opted in by the person; no real home is changed by fixture tests | trusted-default/unsafe-default startup consent, all-project preview/apply, init inheritance with unchanged absent-file ask defaults, and isolated per-home plugin/hook setup/status tests; #1069 covers preserving project/local plugin rows while configuring only user scope, plus recording `start.agents` after a failed home step; metric: applied/refused registered targets and missing/unknown discovered-home states; native Orca receipt remains T4 |
|
|
@@ -54,12 +59,15 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
54
59
|
| Symbol preparation and historical recall (#684 phase 3 follow-ups) | off until release | exists calls per no-reviewer completion; raw-signature fail recall; indexed-definition/unknown labels; unchanged note/candidate bytes and neutral cleanup failures |
|
|
55
60
|
| Overlap notices | on; plan symbols match by normalized name (arguments stripped, a bare name matches the last segment, two qualified names must be equal; #682 phase 1b) | `ahub report`: overlap warnings, task pairs; false-overlap rate, and symbol-only matches on bare common names (#682) |
|
|
56
61
|
| Backlog phase grooming and issue planning (#759) | off until released and the running hub supports the new planning fields; relinks for cards #138/#287 remain a post-landing planner action | related-phase duplicate count; unrelated same-issue duplicate controls; planning revisions with `fields: ["sdlc"]` or `[]`; old spec acceptance absent after relink/undo |
|
|
62
|
+
| Person-run backlog legs (#1176, `needsPerson`) | on after release: this repository parks live-receipt legs (tasks 138, 181, 188, 468, 594) reserved to an agent only as a placeholder; marking them `ahub backlog person <id> <rev> true` keeps the hint and stops auto pull and the idle sweep offering them | `ahub backlog list` ends with `waiting on you: #N...` and `ahub status` carries `WAITING ON YOU`; the `backlog pulled` and `idle sweep` history of a marked card stays empty; `test/person-run-cards.test.ts` pins every gate. Marking the five tasks is a person's command after release, not part of the PR |
|
|
63
|
+
| Backlog return with a reservation edit (#1177, #1154) | on after release: a person or planner moving an untouched card to another peer, or parking it with no reservation, runs `ahub backlog return <id> <rev> <reason...> --reserved <peer>` or `--unreserve` instead of a plan then a return | the card's history shows one `backlog returned` entry carrying the reservation change (not a separate `planned` entry before it); `test/backlog-return-reserved.test.ts` runs the real CLI against a daemon for both flags, the default and the refusals |
|
|
57
64
|
| Planner WIP caps and backlog pull (#655, #718) | on (`tasks.wip_limits.codex = 2`); reserved-pull handoff on after release; the active / review-wait / reserved split (#784) shows in `ahub status`, the console Peers detail and the dashboard legend after release | `ahub status` split per peer (a full cap held by review-wait shows as such); board history/offer readback: reserved `backlog pulled` -> `assigned` -> `accepted` for the same peer; stale or unowned offers, capacity refusals and held-ready entries |
|
|
58
65
|
| Planned backlog starts (#1076) | source/fixture coverage; active after release and hub upgrade | future planned cards appear as `scheduled` in planner grooming; no auto-pull, `backlog_ready` notice or ready-queue owner offer before `plannedStart`; exact-boundary and after-date eligibility; queue-pressure origins remain retryable until due |
|
|
59
66
|
| Task sweep (stalls, idle owners) | on | stall and sweep events per week |
|
|
60
67
|
| Turn-free coordination | off: experimental; needs a separate measured trial | coordination events, conflict notices |
|
|
61
68
|
| Pull-only peers (agy) | on; `hub_inbox` drains to 64 KiB (#713) | unread offers, empty-inbox polling (#681); queued count and oldest queued age per pull-only peer in `ahub status`; reads that said `N more waiting` |
|
|
62
69
|
| Bulk clear of failed queue rows and the settled-row filter (#1096, `queue_discard_states`) | on after release and upgrade: `ahub queue discard --peer <id>` also takes the peer's unsettled failed rows and `ahub queue list` hides settled rows (`--all` shows them); fixture coverage only (`test/queue-discard.test.ts`: real daemon and CLI, a fake old hub for the capability refusal). A person using it on a real backlog is not yet recorded | `ahub queue discard --peer` runs that name a failed count, `queue list` stderr lines `N settled deliveries hidden`, and the failed-row count per peer in `ahub status` falling after a discard; a refusal that names `queue_discard_states` means an older hub is still running |
|
|
70
|
+
| Failed-delivery cause and status signal (#1178) | source and isolated fixture coverage after validation; active after release and hub upgrade; real-backlog use is not yet recorded here | `ahub queue show` and `queue list --json` expose the fixed public-safe cause (legacy absence stays unknown); `ahub status` names each nonzero unresolved failed count and the peer-specific discard step; resolution removes the count, including retry parents; new journal, bus, output and daemon regressions cover cause privacy and metadata-only counts |
|
|
63
71
|
| Completed-change notices, grouped and superseding (#713) | on after release; accepted tasks only | queued `is done and touches` notices per peer (one per done, not per task and per repeat); `superseded completed-change notice` discards; `ahub queue discard` uses |
|
|
64
72
|
|
|
65
73
|
## Review and lifecycle
|
|
@@ -73,6 +81,8 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
73
81
|
| Console symbol-overlap advice (#684, #379) | on after release; read-only task detail, observed names only | other task IDs/shared paths and screened different-symbol verdict; no pair involving PII, no claim on unknown/incomplete evidence |
|
|
74
82
|
| Dashboard task sheet Code group (#684 phase 2c) | on after release; read-only, observed names only, none for a private task | task sheet Code group shows the changed symbols or `unknown (no code facts)`; symbol clicks that reach a non-empty graph once phase 3 lands |
|
|
75
83
|
| Review brief, review findings, Important gate (#481 S3) | advise | Important findings per PR, rounds to approval |
|
|
84
|
+
| Anchored review comments and findings (#1056) | source and synthetic-fixture coverage; active after release and hub upgrade; the owner's live document package-format confirmation remains open | draft/edit peer turns (target 0); one envelope and one history count per explicit Send; anchored/moved/outdated/unavailable counts; console-only refusals and quote/body canaries in logs, capture and public views; immutable shared acon fixtures; explicit refresh, task-bound memory versus current-turn capture scope, pruned reviewer requests, refused terminal resend, anchored-batch sibling remember/propose refusals, invocation answers after mid-turn inbox pulls, actionable provenance refusals, anchored-submission final-answer/history canaries, same-session restart retention, real sessionless WsPeer handoff and ordinary-input release, unidentified earlier-SID holds and reconnect status, safe first-SID confirmation, legacy coverage completion and NULL-receipt pruning, corrupt-provenance status, clean new-session admission, evidence-backed sticky restored pull-only holds, saved-package recovery and final-only resolution regression fixtures |
|
|
85
|
+
| Memory sync health and write policy (#1173, #743) | source adoption of exact-pinned agent-mem 0.21.0 and isolated fixtures; not deployed here; AC4 bounded diagnostics available, AC5 successful-result count projection only; default-host v3 sync lacks fresh-attestation integration; legacy activation blocked on agent-mem#281; #1173 stays open; activation, live rollout and successful person-home sync unverified | automatic sync outcome/cause/count; SDK successful-placement result projection with withheld/exported counts (fixture seam; active-v3 sync unverified); legacy declined-sync refusal names inactive placement and the missing core activation command; bounded SDK inspection of physical declined IDs and safe rule categories, with explicit incomplete results; one failure log per unchanged known signature; existing declined long-write and kept-short promotion fences |
|
|
76
86
|
| Spec acceptance (#481 S1) | advise | build entries without acceptance |
|
|
77
87
|
| Lifecycle identity linked by the hub (#694, #723) | on in advise; links at propose and accept from the title and `refs.repo`, with a groom backfill as the safety net | open tasks still showing `issue identity missing` right after propose (should be only titles that name no issue or a qualified title without `refs.repo`) |
|
|
78
88
|
| Planner plan review (#481 S9) | advise | plans reviewed before build |
|
|
@@ -163,6 +173,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
163
173
|
| Cross-hub read invocations (#446 X6) | off until both persons expose peers and independently pin the exact capability/digest/read class; discovery is manual; two-daemon broker/crypto fixtures are the verification target, live X7 receipts remain unverified | source/target invocation ids, request admission versus capability result and result transport outcomes; needs_review counts and no duplicate native dispatch |
|
|
164
174
|
| Dogfood scorecard (#687) | on after release; read-only weekly receipt | `ahub report --dogfood --since 7d --json`; bounded evidence and explicit unknowns |
|
|
165
175
|
| Claim verdicts and fact_check provenance (#901) | source/fixture coverage; the live research pilot (a person entering verdicts with `ahub task claim`) remains unverified | `ahub report --dogfood` research rows: `claims.reachedPersonVerdict`, per-slot `personVerdict`/`modelLabel`/`agreement`, `factCheck.selection`/`passed`/`failed`/`missingKeysPerRun`; null until a verdict or a keyed check is recorded |
|
|
176
|
+
| Claim evidence links (#931 T1) | source/isolated fixtures after merge; this dev-profile repository publishes no evidence writer and has no live research evidence pilot | binding from `hub_task_show` / `ahub task show --json` records support/counterevidence and refuses after a claim edit; PII/Dev views expose no bindings; unknown/stale/private/foreign writes leave no revision, duplicate replay adds none, changed links retain prior revisions; ids-only receipts and capture canaries; projection/Unicode resolution, private-upgrade readback and synthesis readiness remain T2/T3, not verified by T1 |
|
|
166
177
|
| Research campaigns (#930 T1) | source and CPU-only fixtures; no real campaign here; the public study CLI and tools are the T3 row below | draft versus child counts, stable unit/task ids across approved revisions and restart, intake reuse, stale role/source/revision refusals, private views, rollback and research_records recovery floors; no live/model receipt claimed |
|
|
167
178
|
| Study CLI, tools and readback (#930 T3, #601) | Fake peers and a real daemon over its control socket, plus the real `ahub` process against that daemon; no native peer or live model has run a campaign here, so fake versus native evidence stays separate (the `research-live-example` claim in docs/profiles.md is still open) | `test/study-daemon.test.ts` (person's draft, approve and close; no agent reaches an approve or close op; planner drafts and cannot approve; read-only show; a private source shows no source id, question, scope or path; handoff only from the bound owner with every missing field named; the three-source, two-peer example moving from none to incomplete to complete), `test/output-cli.test.ts` (parse before connecting, `--json` byte for byte), `test/study-guidance.test.ts` (guidance names only published tools) |
|
|
168
179
|
| Research dispatch and coverage (#930 T2) | Source/isolated fixtures only; no live research campaign | `test/research-dispatch.test.ts` and projection/recovery fixtures: no expired/revised dispatch, named-budget coverage, handoffs and shared ledger |
|
|
@@ -182,7 +193,11 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
182
193
|
| Guarded merge and result recording (#786 T1/T2, #899) | `auto_merge = "dry-run"` first in this repository's `.agenthub/sdlc.toml`; `on` after one dry-run report matches a manual merge; the report prints for a person by default and as a document with `--json` | `ahub sdlc merge <task> --dry-run` reports the mode, the decision, each refusing gate and the `gh` command it would run, readable without `--json`; `--json` is byte for byte the view printed before #899 (`test/sdlc-output.test.ts`); merges the hub made against merges a person or reviewer made by hand; host merge/cleanup records and owner-notice status; fake-gh ordering/idempotency proof, no live cleanup claim |
|
|
183
194
|
| Peer `DOING` column (#878) | on after the release for Claude sessions started with `ahub claude` and the Codex TUI; ACP peers show it only when their agent sends a plan | `ahub status` shows a title or current item for an active Claude and Codex peer without a hub tool call; `[private]` during PII work; the column disappears when no peer has a value |
|
|
184
195
|
| Pi/local session titles (#1055) | available after release for hub-owned Pi/local sessions; native Pi setter/readback is probed, installed use and the live restart receipt remain unverified (#1143) | first `hub_set_title` succeeds once, later agent writes return `already_named`, and person rename replaces it; live status shows the title or a screened unnamed label while `status.json` omits both |
|
|
196
|
+
| Floating pet retirement (#1012) | pointer available after release; acon Mini use on this repository remains unverified | `ahub pet --window` and `--window --close` print the `acon ui` Mini pointer with exit 0 for person/agent/live-test; no window host starts; retired `--palette` prints the same pointer without writing config, legacy `pet.window` is ignored once, terminal pet frames remain covered by their unchanged tests |
|
|
185
197
|
| Console and dashboard | on; #719 pending-history reads and bounded native launch retries take effect after release | control-request latency, connection timeouts and launch retry notices; daemon CPU/RSS samples, measured separately from lifetime CPU |
|
|
198
|
+
| Completions: a run a person started settles into a result record (#1054 T2/T3, `completions`) | source and fake-adapter coverage only until released: a completion exists only for an adapter with a code-verified settle signal (Claude, Codex, Pi, local, Kimi/Jcode headless, Qwen); Kimi in its own TUI, agy and person-typed Codex turns create none, so this repository's TUI-driven agents (Claude, Kimi) will show few until a signal lands. The person reads them with `ahub results` (unread marked, `--read`, `--read-all`, `--unread-last`), as a `watch` need in `ahub status` and `ahub console` (and, from #1054 T6, in the Results section of the Agents view and in the acon inbox: see the next row) | `completion` events count `done`, `failed`, `limit` and `interrupted` with `ms`, and `completion_seen` events count how many results a person actually read and on which surface (the share of unread results older than a day shows whether results are noticed at all); the share of `interrupted` over all shows how often a restart cuts a run, and a run that never settles shows as an open row in `hub.db` `completion_runs`; `test/completions.test.ts`, `test/completions-daemon.test.ts` and `test/completions-receipts.test.ts` pin the rule, AC1 to AC7 and the privacy sinks; no prompt or reply text is ever stored |
|
|
199
|
+
| Results in the dashboard and the acon inbox (#1054 T6, T7) | on after release; with a console that advertises `inbox.result` and `action.meta` (acon 0.1.3 does) the person sees unread results as `result` items in the acon inbox, and in any case in the Results section of the Agents view with Mark read, Mark all read and Mark last unread again; the one-line detail is the head of the request, read from the bus at display and never stored. This repository's TUI-driven agents (Claude, Kimi) create few completions until a settle signal lands, so the first live receipt is a headless run or a Codex or Pi session started from the console | the share of results marked read from `acon` versus `dashboard` versus `terminal` (`completion_seen` `surface`), how many unread results are older than a day, and whether any `result` item reached an acon console without the features (it must not: the plugin publishes only with both); `test/results-plugin-1054.test.ts`, `test/results-dashboard-1054.test.ts`, `test/results-panel-1054.test.ts` and `test/completion-detail-1054.test.ts` pin the item, the receipt authority, the page and the privacy canaries (AC6 plugin part, AC8). The item is checked against acon's own published `inboxItemProblems` and `stableAtProblems` (`@staix/agent-console/conformance`, 0.1.3), but it is not yet seen in a running acon console: that is the one open live receipt, and it needs acon with `inbox.result` and a person |
|
|
200
|
+
| Questions for the person: `hub_ask` (#1053 T2 to T6, `questions`) | available after release; source and fake-adapter coverage only: no live receipt per client yet (T1 measures the MCP tool-call timeouts and confirms the 45 s and 300 s wait windows). A person answers in `ahub console` (`A`), with `ahub answer`, or in the acon inbox form where the console advertises `inbox.form` and `action.meta` (the form rendering is agent-console#27; before it ships the item is a plain decision with an `open` verb) | `question` events count `asked`, `answered`, `pending`, `superseded`, `cancelled`, `expired` and `unavailable` with `latencyMs` and `surface` (`terminal`, `console` and `acon` show which surface people use); the share of `pending` over `asked` shows whether the wait window is long enough, `expired` shows questions nobody saw, the `question` need in `ahub status` shows how long a question waits, and `test/questions.test.ts`, `test/questions-daemon.test.ts`, `test/questions-console.test.ts`, `test/questions-console-daemon.test.ts`, `test/questions-plugin.test.ts` and the Pi bridge test pin the paths; no question or answer text is ever in the events, the log or memory |
|
|
186
201
|
| Usage view (#683) | CLI (`ahub usage`, U2), console Usage tab `7` (U3) and dashboard Usage view (U4) shipped | its own panels |
|
|
187
202
|
| Kimi usage from its wire log (#285 phase 2) | on after the release when `budget.kimi_tokens_5h` is set; this repository sets it | `tokens` and `usage` (`kimi_wire`) events per Kimi turn, the `tokens` window in `ahub budget`, and the count of `kimi usage unknown` notices; the live check against Kimi's `/usage` (AC11) stays opens |
|
|
188
203
|
| Doctor memory-capture rows from agent-mem setup state (#1008) | on after release; `ahub doctor` runs here and reads `amem setup <tool> --json` (a preview that writes nothing) for `codex` and `kimi`; no dotfiles text and no `dot ai memory status` call | `memory capture: codex` and `memory capture: kimi` rows read ok (set up), warn with `amem setup <tool> --apply` (pending), warn with `client missing` (the native CLI is not installed) or unknown (no `amem`, a refusal or unparseable output); the Codex row notes the native `/hooks` review; a fixture run proves `dot` is never called |
|
|
@@ -198,6 +213,9 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
198
213
|
| Benchmarks (#251, #637) | off: `bench.enabled = false`. The task-routing gate (#637 part 1) is on in CI for every PR: `routing-receipt` fails a change to `templates/routing.toml` without a matching receipt; the model-routing gate (#637 part 2) is the second step of the same workflow: `scripts/check-model-routing-receipt.ts` fails a change to the model-routing keys without a matching `-modelrouting-` receipt, and wants a by-hand `--live` half when an alias or judge moves | bench receipts; `docs/verification/*-routing-*.md` and `*-modelrouting-*.md` receipts; a `routing-eval` check run on every PR with `eval_pass_rate=` and `eval_suite=` in its title (name it as `eval_check` to make it the eval gate); `bun scripts/benchmarks/routing-gate.ts` and `model-routing-gate.ts` print the default's numbers (100% on both splits); the live half (served model ids) has not been run against a gateway yet |
|
|
199
214
|
| Disposable smoke runner (#787 Q2) | off on this repository: it refuses this checkout; use a new temporary fixture; real-account Q2 remains unverified | sanitized receipt checks/counts/timings, zero owned survivors on timeout; fake transport tests are separate |
|
|
200
215
|
| Plain corpus evidence in ask and task briefs (#510b) | off here until a person configures plain `corpus.paths`; vaults remain refused; no corpus body is written to amem | `note:<path>#heading` ids in ask evidence or public task briefs; PII/deny and stale-context refusal regressions |
|
|
216
|
+
| acon inbox snapshot speed and bound (#727, #1196) | on after release and `ahub setup`: the acon plugin asks every running project at once (not one after another), shares one computation among concurrent polls, serves a result younger than 1 s as it is and one up to 10 s old at once while one refresh runs, drops the cache on any action, waits at most 2 s for a project and keeps that project's last rows meanwhile, and returns at most 50 items (decisions first, then reviews, results, candidates, alerts) with a `more` count. Measured on the owner's Mac before the change: 2.5 s for 434 B in the console, 0.84 s median when run alone here, against a 2 s `pollMs`. Unverified: the owner's live console p95 after the change | the inbox `snapshot` wall time seen from the acon console on the owner's Mac (target p95 under 1 s), `test/acon-inbox-727.test.ts` (parallel asking, one computation for 20 callers, cache and background refresh, invalidation by an action, the 50-item bound and `more`, the project budget and a p95 over a five-project fleet), and the uncached median over this machine's real registry (0.84 s before, 0.37 s after) |
|
|
217
|
+
| Global CLI and plugin step after `ahub upgrade` (#718, #1179) | on after release: a completed or scheduled upgrade ends with `bun add -g @staix/agent-hub@<version>` and `ahub setup` when the global CLI or the shared Claude plugin is older than the daemon it installed (a handed-over upgrade speaks for the older CLI that started it), and says nothing when both are current or the plugin cannot be read; `release-prepare` writes the same step into every new `Upgrading to <v>` note and `release-tag` refuses a release without it. Unverified: a live handed-over upgrade on the owner's Mac, where the old CLI starts the new coordinator through `bun x` | the upgrade's own output on the owner's Mac after the next release, whether `ahub doctor` still warns afterwards (it should not once the person followed the step), `test/runtime-version-warning.test.ts`, `test/upgrade-interactive.test.ts`, `test/upgrade-cli.test.ts` (a real hub with a fake `claude` and `npm`), `test/release-prepare.test.ts` and `test/release-tag.test.ts` |
|
|
218
|
+
| Hard-coded values inventory ratchet (#719, #1180) | on now: `scripts/check.sh` runs `bun scripts/inventory-hardcoded-values.ts --check`, so a new constant must be classified in `scripts/inventory-hardcoded-values.classifications.json` before it merges, and the 1222 keys still unclassified sit in `scripts/inventory-hardcoded-values.baseline.json`, which only shrinks. This does not close #1180: those 1222 are classified later in reviewed batches (`docs/verification/2026-11-05-hardcoded-values-ratchet.md`) | the unknown-key count (the baseline's length) falling to 0 over the follow-up batches and `check: OK` staying green with no key added to the baseline, `test/inventory-hardcoded-values.test.ts` |
|
|
201
219
|
|
|
202
220
|
## Decisions
|
|
203
221
|
|
package/docs/events.md
CHANGED
|
@@ -46,6 +46,9 @@ marked `private: true`, and PII tasks `pii: true`.
|
|
|
46
46
|
| `permission_mode` | `peer`, `from`, `to` (`ask`, `ask-when-needed`, `never-ask`): a person set a peer's permission mode (`from` equals `to` when it was already in force) or confirmed a never-ask default (issue #242) |
|
|
47
47
|
| `settings` | `key` (a registry key such as `permission.kimi` or `routing.classes.implement.peers`), `from`, `to` (the value before and after: the one in force for a setting that applies at once, the stored one for a setting read at a start; a closed word, a boolean, a list of peer ids, a route id, or null for none), `source` (`dashboard`, `terminal`), and `undo: true` for an undo: a person changed a setting from the dashboard or `ahub settings` (issue #269). A mode change also writes its `permission_mode` event |
|
|
48
48
|
| `permission` | `id`, `peer`, `event` (`requested`, then one of `answered`, `expired`, `cancelled`) and, on the closing event, `latencyMs`, `surface` (`console`, `dashboard`, `terminal`: where a person answered; absent when the hub closed the request) and `option` (the kind of the option chosen: `allow_once`, `allow_always`, `reject_once`, `reject_always`): one approval request relayed to the console and how it ended. `expired` is `approvals.timeout_s` without an answer. `cancelled` with a `surface` is a person's deny in the console or by `ahub permit <id> deny` (a deny on the dashboard is `answered` with a reject option); without one, the hub withdrew the request (its call or turn ended, the peer was stopped, or the hub is stopping). Never the title or the tool |
|
|
49
|
+
| `question` | `set`, `peer`, `event` (`asked`, `answered`, `pending`, `superseded`, `cancelled`, `expired`, `unavailable`) and, where they apply, `latencyMs`, `person` (only with `surface: acon`: the console's verified identity, one bounded line), `surface` (`terminal`: `ahub answer`; `console`: the `A` key; `dashboard`: reserved, no surface sets it today; `acon`: the plugin's answer with the console's person meta), `reason` (`superseded`, `stopped`, `turn_aborted`, `session_changed`, `expired`, `unattended`), `questions` (a count) and `private`: one question a peer asked the person through `hub_ask` and how it ended (#1053). Never a prompt, an option, an answer or any other text. The attention need a question raises (`question`, in `status.needs` and `attentionItems`) is not an event: it carries the set id, the peer and the time only |
|
|
50
|
+
| `completion` | `id`, `peer`, `outcome` (`done`, `failed`, `limit`, `interrupted`), `ms` (start of the run to settle): a run a person started settled (#1054). A run starts at the `turn_start` that consumes the person's message and settles only when the adapter's `settle` signal fired and nothing else is pending (no queued continuation, open permission or question, owned child, running check or held delivery); a restart cut short settles `interrupted`, once. An explicit person Stop and a budget pause create none. Never the prompt, the reply or any other text: the envelope ids live in `hub.db` and are read through the usual privacy path |
|
|
51
|
+
| `completion_seen` | `id`, `surface` (`terminal`, `console`, `dashboard`, `acon`): a person marked a result read (#1054). One per receipt written, never from a snapshot read or a listing, never the prompt or the reply. `surface` is where the person marked it: `dashboard` is the Results section of `ahub ui` and of the acon panel (the panel's own buttons), `acon` is the acon inbox's `result_seen` or "Mark all read" with the console's verified person meta, `terminal` is `ahub results`. Mark-unread deletes a receipt and records no event. The detail line shown beside a result (the head of the starting prompt) is built at display and is in no event |
|
|
49
52
|
| `pii_screen` | `task` (absent for a budget hand-off or a note not about a task), `item` (`task`, `summary`, `review note`, `handoff`, `note`), `label` (`pii`, `clear`), `source` (`regex`: a pattern matched and no call was made; `screen`; `unknown`: no verdict, handled as PII), `category` (`name`, `student_id`, `phone`, `address`, `grade`, `health`, `other`), `miss` (why there was no verdict: `too long`, `off campus`, `timeout`, `unreadable`, `failed`), `ms` (absent for `regex`): one PII screen verdict while `signals.pii_screen = "local"` (issue #198); never the text |
|
|
50
53
|
| `context_pressure` | `peer`, `source` (`claude_statusline`, `codex_token_usage`, `acp_usage_update`), `measuredAt` (epoch ms of the reading), `used` (the fraction of the context window in use, 0 to 1), `window` (its size in tokens, or null): a fresh reading of a peer's native context reached `context.gate`. Recorded once per crossing, until a reading below the gate or a new native session rearms it, and not while the peer is paused or offline or the hub is in recovery or stopping |
|
|
51
54
|
| `quota` | `peer`, `windows` (`id`, `used`, `resetsAt`), `hard`, `measuredAt` (when the reading was taken, if not when it arrived: Claude's numbers come through a file) |
|
package/docs/memory.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Hub memory integration
|
|
2
2
|
|
|
3
|
-
Agent-hub consumes the exact-pinned first-party [`@staix/agent-mem`](https://github.com/STAIxBWLB/agent-mem) library (
|
|
3
|
+
Agent-hub consumes the exact-pinned first-party [`@staix/agent-mem`](https://github.com/STAIxBWLB/agent-mem) library (the exact pin is in [package.json](../package.json); initial pin `0.1.1`). The package owns portable storage, tiers, graph, goals, sync, import and raw commands. Agent-hub owns caller authority, current project privacy policy, task lifecycle integration and presentation. Claude-mem is an optional, explicit import source only; runtime recall and capture make no worker HTTP requests.
|
|
4
4
|
|
|
5
5
|
## Portable core and data directory
|
|
6
6
|
|
|
@@ -260,3 +260,19 @@ Only an open, visible Memory view requests dashboard code work. Console task det
|
|
|
260
260
|
Machine-local `corpus.paths` can supply public `note:<path>#heading` evidence to `ahub ask` and task briefs. It is separate from durable amem notes: the hub writes no corpus body into the index or store, never reads an Obsidian vault from disk, and applies deny/`pii.paths` before reads and full-note screening before excerpts. Native memory counts exclude corpus rows. Existing brief item caps and priority fail notes remain in force.
|
|
261
261
|
|
|
262
262
|
PII questions and private task contexts do not query the corpus or shared observers. PII ask inference requires a positive `onCampus()` result, the pinned local fixed model and `onCampusOnly: true` through dispatch; unknown locality returns evidence without a model answer. Task/privacy/policy changes across awaits discard a brief before observation. Ask answers recheck the PII and note-PII verdicts of their gathered task rows and the caller-private context before dispatch and publication; unrelated board activity does not discard an answer. Corpus paths may be enabled with memory off; they are never exported as persistent memory automatically.
|
|
263
|
+
|
|
264
|
+
## Automatic sync health (#1173)
|
|
265
|
+
|
|
266
|
+
Profile readiness and sync health are separate. `ahub status` and the dashboard Memory row show the current daemon's last automatic sync attempt: not run, not-configured, stopped, ok, or failed with a closed cause, declined count when known, and a next step. Upstream error text, remote URLs, row IDs and private patterns do not enter this status. This state is process-local; a restart starts at not run until its first attempt. Missing remote configuration is the neutral `not-configured` state; an interrupted/stopped attempt is neutral `stopped`. Both keep their safe next step and produce no failure log under `quietSyncError`. A successful attempt resets the failure episode.
|
|
267
|
+
|
|
268
|
+
Sync uses the configured agent-mem standalone policy, narrowed by the hub's current deny paths, PII patterns and project-private paths. Direct long-term writes clear that same policy before append. The core promotion callback rechecks each authored note payload: a declined note stays short while allowed notes can promote. Source logs are not rewritten. A policy is captured per attempt; the existing profile/selector and hub policy-version fences still apply, without claiming an atomic cross-process policy transaction.
|
|
269
|
+
|
|
270
|
+
An unchanged failure emits one safe log line per episode. A complete bounded policy inspection identifies the declined ID set for failure dedupe without logging those IDs or their text. An incomplete or unavailable inspection keeps the set explicitly unknown rather than treating it as empty. Other failures use a private error hash; no raw error enters status or logs.
|
|
271
|
+
|
|
272
|
+
`ahub memory declined [--json]` is a person-only, read-only inspection. It reports physical outbound row IDs and safe policy categories, never title, body, path nodes or literal private patterns. Reads defer promotions and recheck the profile binding. Forgotten originals still matter: `forget` changes materialized visibility but leaves the source row in append-only history. Do not use it as a promise to clear a sync refusal.
|
|
273
|
+
|
|
274
|
+
The exact-pinned agent-mem 0.21.0 supplies bounded `inspectSyncPolicy` inspection for shared-v1 and generation profiles. A complete result lists the declined IDs and safe rule categories for the inspected physical outbound history, including originals hidden by a later forget. An unavailable, stale or bounded-out inspection remains explicitly incomplete; it never proves that no declined rows exist. The hub uses the public SDK rather than private helpers, snapshots of full history or its own portable log reader.
|
|
275
|
+
|
|
276
|
+
The package also owns per-row local placement. The hub adopts only the projection of a successful trusted SDK placement result: `ok` with its verified withheld/exported counts. This is tested through an injected SDK-result seam, not an activated store. Agent-mem 0.21.0 requires a fresh `placementAttestation` for each v3 sync; the default hub does not supply one, so its active-v3 sync remains unsupported until legitimate host-attestation integration is added. The hub never fabricates that proof. Count projection does not delete or rewrite notes, change policy or promote a declined row; transport failures remain failures.
|
|
277
|
+
|
|
278
|
+
Legacy stores without active per-row placement still refuse a sync containing declined rows. Agent-mem 0.21.0 provides no activation command; the hub neither invents one nor supplies a local fallback or fabricated activation proof. The missing core activation path is tracked by [agent-mem#281](https://github.com/STAIxBWLB/agent-mem/issues/281). Complete bounded diagnostics address #1173 AC4; The AC5 result projection is ready, while default-host active-v3 sync still requires supported activation and fresh-attestation integration. #1173 remains open until #281 ships and the hub adopts its supported path. Source adoption and isolated fixtures do not establish activation, deployed behavior or a successful sync of the person's memory home.
|