@staix/agent-hub 0.12.30 → 0.12.31
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 +21 -0
- package/README.md +21 -7
- package/docs/agent-notes/adapters.md +2 -1
- package/docs/agent-notes/budget.md +1 -1
- package/docs/agent-notes/bus.md +4 -0
- package/docs/agent-notes/daemon.md +5 -2
- package/docs/agent-notes/local-worker.md +2 -0
- package/docs/agent-notes/tasks.md +5 -0
- package/docs/agent-notes/tests.md +5 -2
- package/docs/memory.md +1 -1
- package/docs/operations.md +129 -22
- package/docs/quickstart.md +17 -2
- package/docs/security.md +30 -2
- package/docs/specs/2026-09-19-agent-hub-design.md +37 -3
- package/docs/specs/2026-09-20-upgrade-recovery-design.md +84 -10
- package/docs/verification/2026-10-17-0.12.31.md +71 -0
- package/docs/verification/2026-10-17-418-probes.md +21 -0
- package/docs/verified.json +13 -13
- package/package.json +1 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +66 -19
- package/src/adapters/claude-channel.ts +29 -11
- package/src/adapters/local-worker.ts +2 -2
- package/src/adapters/pi.ts +5 -0
- package/src/cli/attention.ts +5 -1
- package/src/cli/console-state.ts +56 -12
- package/src/cli/console.ts +19 -6
- package/src/cli/identity.ts +3 -2
- package/src/cli/jcode-mcp.ts +1 -1
- package/src/cli/main.ts +8 -1
- package/src/cli/output.ts +13 -2
- package/src/cli/upgrade-interactive.ts +2 -1
- package/src/cli/upgrade-restore-state.ts +133 -0
- package/src/cli/upgrade-runtime.ts +162 -58
- package/src/cli/upgrade.ts +49 -24
- package/src/hub/board.ts +82 -24
- package/src/hub/bus.ts +78 -29
- package/src/hub/check-runner.ts +514 -0
- package/src/hub/child-process.ts +1 -0
- package/src/hub/control-client.ts +5 -1
- package/src/hub/daemon.ts +400 -67
- package/src/hub/delivery-hints.ts +30 -0
- package/src/hub/delivery-journal.ts +185 -12
- package/src/hub/delivery-superseded.ts +52 -0
- package/src/hub/envelope.ts +1 -1
- package/src/hub/host-executable.ts +11 -0
- package/src/hub/hub-tools.ts +9 -1
- package/src/hub/peer-catalog.ts +3 -0
- package/src/hub/routing.ts +35 -16
- package/src/hub/settings.ts +2 -1
- package/src/hub/spec-read.ts +120 -0
- package/src/hub/supervision.ts +21 -6
- package/src/hub/task-sweep.ts +7 -6
- package/src/hub/tasks.ts +173 -34
- package/src/memory/capture.ts +2 -1
- package/src/ui/index.html +12 -9
- package/src/ui/needs.ts +7 -5
- package/src/ui/office-model.ts +4 -1
- package/src/ui/task-board.ts +1 -1
- package/src/ui/task-progress.ts +6 -2
- package/templates/AGENTS.block.md +1 -1
- package/templates/profiles/general.json +1 -1
- package/templates/profiles/research.json +1 -1
- package/templates/profiles/writing.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
Issue and pull request numbers in the entries for 0.7.7 and earlier refer to the previous repository, archived on 2026-09-30 when this repository's history was rewritten; the one exception is the open smoke-check issue, formerly #12, which moved here as #1. Numbers in newer entries refer to this repository.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## 0.12.31
|
|
8
|
+
|
|
9
|
+
After upgrade, Jcode projects need the one-time MCP rewrite below. Cancellation requires a daemon advertising `task_cancel`; controlled downgrades refuse while cancelled rows exist (an old binary started by hand remains outside that protection). The repository now requires the `seeded guards` check. Installed managed-Pi #418 AC8 (#142), cancellation/sweep #438 AC7 and the native legs in #273/#1 remain unverified by this release preparation. Installation and the person's restart require separate receipts.
|
|
10
|
+
|
|
11
|
+
- Retry an addressed uncertain delivery once, retaining message-only lineage evidence and excluding shared hub presence; delivery-only local/ACP peers leave resolution to the person. Run `ahub jcode --mode headless` once per Jcode project after upgrade, before conductor or dashboard starts of Jcode, to update its owned MCP entry (#448, #434).
|
|
12
|
+
- Add cause-deduplicated stalls, durable unread pull-only offer attention, a guarded ready-unassigned sweep and revision-checked cancellation that preserves history without approving work or releasing dependents; refuse cancellation on older daemons and controlled downgrade with cancelled rows (#460, #438).
|
|
13
|
+
- `seeded guards` is now a required check (repository setting after #458). CI runs its four shards beside both OS checks, reads Bun from `.bun-version`, updates pinned actions and covers actions with Dependabot; the release gate refuses tags not on `origin/main` and separates OIDC npm publication from GitHub Release creation (#458, #457).
|
|
14
|
+
- Wait for a pending managed terminal's authenticated session with explicit pending/waiting/done/failed restoration receipts and exact terminal fences, preserving completed conversations and the bounded no-duplicate-launch rules (#435, #433).
|
|
15
|
+
- Record agent-mem co-development and the claude-mem capability freeze in project instructions; new portable memory functionality belongs in agent-mem and the hub keeps its exact pin (#436).
|
|
16
|
+
- Safely return unseen Claude pushes, settle only provably moot hub-only holds, preserve stop notices and shared presence, show every hold and identify inherited agent markers in refusals (#440, #434).
|
|
17
|
+
- Follow new Events rows while at the tail, preserve a row selected for reading and add Home/End or </> navigation to console panels (#442, #441).
|
|
18
|
+
- Add bounded authenticated task-spec reads and opt-in isolated exact-head container checks; non-PII local/Pi implement, test and bulk_edit owners need available checks, and issue-backed owners in every class need spec access. Designated reviewers are exempt from these owner gates; PII work remains local-only without the opt-in (#443, #418).
|
|
19
|
+
- Instruct pull-only Kimi sessions to check the hub between work steps and share blockers or changed contracts through the addressed hub tools (#444).
|
|
20
|
+
- Open the dashboard with console `w`, the pet window with `o`, or the allowed `:ui` and `:pet` commands (#453, #452).
|
|
21
|
+
- Keep waiting through late launcher records and id-less attachments, ignore offline session ids and use the operation's preserved-source coordinator when an older CLI mislabels tagged recovery receipts (#454, #433).
|
|
22
|
+
- Designate an exclusive planner with the live `planner` setting, choose one automatically when needed and display or change it through status, console `l`/`y` and the dashboard (#456, #455).
|
|
23
|
+
- Keep explicit GitHub issue references gated without a GitHub origin, clear warnings after receipt-directory removal and preserve unknown check payloads under the documented retention exception instead of unsafe deletion (#459, #418).
|
|
24
|
+
- Resume an already-committed source through transient connection loss or typed database contention within the existing 30-second shutdown bound, without duplicate prepare, terminal close or commit; retain replacement and pending downgrade fences (#461, #438).
|
|
25
|
+
|
|
5
26
|
## 0.12.30
|
|
6
27
|
|
|
7
28
|
Memory now uses the exact-pinned first-party `@staix/agent-mem` 0.3.0. Do not migrate a memory home until every hub using it runs 0.12.30; run `ahub memory profile-check`, then quiesce and close all consumers before changing profiles. Shared v1 stays the default, with no automatic data migration.
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Codex, Kimi Code, Pi and a hub-owned local worker (Qwen Code and Jcode optional)
|
|
|
5
5
|
share a message bus and a task board per project and one memory on the machine,
|
|
6
6
|
each attached through its own native interface.
|
|
7
7
|
|
|
8
|
-
Status: 0.12.
|
|
8
|
+
Status: 0.12.31, control protocol 16. Bun + TypeScript, one loopback daemon per
|
|
9
9
|
project. Site: [agent-hub.staix.net](https://agent-hub.staix.net).
|
|
10
10
|
|
|
11
11
|
## What it does today
|
|
@@ -16,8 +16,10 @@ project. Site: [agent-hub.staix.net](https://agent-hub.staix.net).
|
|
|
16
16
|
decide what interrupts a turn, and delivery is durable across restarts.
|
|
17
17
|
- **A shared task board.** Tasks are proposed, accepted, done and reviewed through
|
|
18
18
|
hub tools. `routing.toml` assigns owners by task class, roles split planning,
|
|
19
|
-
implementation and review, and
|
|
20
|
-
|
|
19
|
+
implementation and review, and a designated planner can be changed live.
|
|
20
|
+
Cause-deduplicated stalls and unread pull-only offers need attention; cancellation
|
|
21
|
+
closes work without approving it or releasing its dependents. Owners of
|
|
22
|
+
overlapping work are told what changed.
|
|
21
23
|
- **Shared memory.** Decisions, contracts, fails and findings go to the hub's own
|
|
22
24
|
store through the exact-pinned first-party `@staix/agent-mem` library (short-
|
|
23
25
|
and long-term tiers, a typed graph, git sync between machines),
|
|
@@ -38,7 +40,9 @@ project. Site: [agent-hub.staix.net](https://agent-hub.staix.net).
|
|
|
38
40
|
- **Operations.** A terminal console and a local dashboard, one hub per
|
|
39
41
|
repository or worktree with a machine-wide view, and `ahub upgrade` that carries
|
|
40
42
|
running sessions across versions. The console supports revision-checked task
|
|
41
|
-
assignment/unassignment and delivery-queue resolution.
|
|
43
|
+
assignment/unassignment and delivery-queue resolution. Peers with independent
|
|
44
|
+
tool turns can request one uncertain redelivery; the delivery-only local worker
|
|
45
|
+
and headless ACP peers leave held deliveries for the person to resolve.
|
|
42
46
|
|
|
43
47
|
## Where it is going
|
|
44
48
|
|
|
@@ -50,8 +54,9 @@ project. Site: [agent-hub.staix.net](https://agent-hub.staix.net).
|
|
|
50
54
|
and failure-driven management, each shipped only after its contract and a
|
|
51
55
|
measurement.
|
|
52
56
|
- **Every peer able to do its share** ([#418](https://github.com/STAIxBWLB/agent-hub/issues/418)).
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
Bounded task-spec reads and opt-in isolated checks are implemented. Installed
|
|
58
|
+
managed-Pi verification (AC8) remains open; source and CI results do not certify
|
|
59
|
+
that live runtime.
|
|
55
60
|
- **Measured, not assumed.** Add-ons and memory are kept or dropped by controlled
|
|
56
61
|
comparisons ([#248](https://github.com/STAIxBWLB/agent-hub/issues/248),
|
|
57
62
|
[#258](https://github.com/STAIxBWLB/agent-hub/issues/258)).
|
|
@@ -68,8 +73,17 @@ cd <your project> && ahub init && ahub up
|
|
|
68
73
|
`ahub init --dry-run --json` shows what init would write first. While hubs run,
|
|
69
74
|
`ahub upgrade` moves them to the latest release.
|
|
70
75
|
|
|
76
|
+
After upgrading to 0.12.31, run `ahub jcode --mode headless` once in each project
|
|
77
|
+
that uses Jcode to refresh its owned MCP entry before conductor or dashboard starts of Jcode.
|
|
78
|
+
Cancellation needs a daemon advertising `task_cancel`; controlled downgrades
|
|
79
|
+
refuse while cancelled rows exist. For local/Pi implementation, opt in to an
|
|
80
|
+
available `checks.runner = "container"`; issue-backed owners also need authenticated
|
|
81
|
+
spec access. PII work and designated reviewers retain their separate exemptions.
|
|
82
|
+
See [release verification](docs/verification/2026-10-17-0.12.31.md) for the live legs
|
|
83
|
+
still open, including #418 AC8 and #438 AC7.
|
|
84
|
+
|
|
71
85
|
Before migrating a memory home with `amem`, upgrade every hub using that home to
|
|
72
|
-
0.12.30, check `ahub memory profile-check`, then quiesce and close all memory
|
|
86
|
+
0.12.30 or later, check `ahub memory profile-check`, then quiesce and close all memory
|
|
73
87
|
consumers. Shared v1 remains the default; installing this release does not migrate
|
|
74
88
|
data. See [memory profiles and rollout](docs/memory.md#selected-memory-profile).
|
|
75
89
|
|
|
@@ -9,7 +9,8 @@ Scope: the Codex, ACP and Pi adapters and the Pi extension (turn `generation` an
|
|
|
9
9
|
- Codex 0.154.0 `agentMessage` items carry `text` and `phase` (not `content[]`); only the last non-`commentary` message of a turn is shared.
|
|
10
10
|
- Approval titles are agent-written text shown to a person: the daemon escapes control characters, and write/edit/bash show what will be written or run.
|
|
11
11
|
- An ACP permission request may carry no `rawInput` (Kimi 2.0.1): the arguments were on the earlier `tool_call` update, which `acp.ts` remembers by `toolCallId`. Kimi 2.1.1 sends no `rawInput` before the answer at all: the argument JSON streams as `content` text on `tool_call_update`, and only complete JSON counts. A payload that still cannot be resolved, or is too long to show whole (marked `[cut, N chars]`), withholds its `allow_always` option - never render a bare tool name as if it described the call.
|
|
12
|
-
- Tag a Pi hub-tool refusal only at a proven pre-effect guard with `PreEffectToolRefusal`; return its exact error and settle its receipt. Never classify a generic/post-effect/storage failure or a legacy pending receipt from error text or current board state.
|
|
12
|
+
- Tag a Pi hub-tool refusal only at a proven pre-effect guard with `PreEffectToolRefusal`; return its exact error and settle its receipt. Never classify a generic/post-effect/storage failure or a legacy pending receipt from error text or current board state. After durable `markStale`, cancellation or output consumption, retain ordinary failure classification; a later binding/privacy rejection cannot prove that no effect occurred. Recheck task revision, owner/session generation and privacy across awaited bounded spec/check operations; never turn those tools into arbitrary host execution.
|
|
13
|
+
- Hide `hub_delivery_retry` from delivery-only ACP/local tool lists and omit its retry hint. Treat `AGENTHUB_DELIVERY_ONLY` only as an exposure hint; the daemon must refuse by the actual attached adapter, and native children must not inherit the marker. A Claude push that cannot reach its model reports `failed_safe`; if the daemon refuses that optional receipt state, try `needs_review` and retain uncertainty when neither receipt is confirmed.
|
|
13
14
|
- Report each Pi owner exit once, with code/signal (unknown for an unobserved TUI exit), turn/tool activity and only the last tool name. Auto-restart only a current, started, unexpectedly idle headless owner on its verified persisted session, once per 60 s; preserve shutdown/requested-stop/recovery/startup/active-tool fences and never fall back fresh.
|
|
14
15
|
- Pi's `always` grant (#209) is keyed by `executeTool`'s tool name, never parsed from the approval title, and lives only in that Pi start's closure. Never persist it, share it with the local worker, or let the dashboard give it.
|
|
15
16
|
- Auto-approval covers the hub's own tools by exact `mcp__agent-hub__<name>` title and only ever picks `allow_once`. Identity comes from the permission request title or, when an agent titles the request with the argument JSON (Qwen), from the announced `tool_call` title bound to the call id and resolved against the session's configured MCP servers, never from payload text, a prefix or an unrelated display title. Never widen it to a prefix or replace it with an agent-selected session mode. Set Kimi `yolo`/`auto` only for its verified native identity and an operator mode; config never-ask waits for a console y, and other ACP agents stay unmanaged on fresh/resumed starts without setting/resetting modes or failing over their reported mode; refuse runtime changes until their map exists; await the advertised mode change after session new/load and before a prompt, and fail startup on refusal. Use the shared `KIMI_MODE_IDS` mapping in `src/hub/permission-mode.ts`.
|
|
@@ -10,7 +10,7 @@ Scope: quota and native context readings, checkpoints, pause, handoff and resume
|
|
|
10
10
|
- The status line tee must never fail or slow the render: no throw, original command run with the same stdin, 5 s cap.
|
|
11
11
|
|
|
12
12
|
- Keep native context occupancy in `src/hub/context-window.ts` separate from quota accounting; never use Codex's accumulated `total` as occupancy or estimate Pi counters.
|
|
13
|
-
- Context checkpoint completion requires its request id and the current attached peer/native session. Invalidate its transport generation synchronously at a new peer claim, before asynchronous recall or attachment. Never pause, reassign or replace a session on context pressure. Refuse private-turn, PII-pattern and all
|
|
13
|
+
- Context checkpoint completion requires its request id and the current attached peer/native session. Invalidate its transport generation synchronously at a new peer claim, before asynchronous recall or attachment. Never pause, reassign or replace a session on context pressure. Refuse private-turn, PII-pattern and all associated open PII-task summaries (owner or reviewer, including in_review, with the current routing policy; use `isClosedTaskState` to exclude approved and cancelled work) before local persistence or cloud memory; never broadcast checkpoint text.
|
|
14
14
|
- Invalid/stale context readings expose unknown and do not rearm a crossing. Latch a crossing only after its event is accepted; reconsider paused/recovery-held crossings after release with fresh current-session readings. Tee context fields contain finite numeric values or null only, bound to daemon instance, launcher and native session.
|
|
15
15
|
|
|
16
16
|
- A provider hard refusal ends a reading override and supersedes a soft evaluation still awaiting its checkpoint; never let the obsolete checkpoint overwrite that pause. An ACP provider quota refusal reports a hard budget reading and confirms the live pause before the adapter requeues work, so the pause fences retries and the existing relay handles assignments. Use the observed window length for an unknown reset; repeated quota refusals while paused do not consume poison-envelope retries.
|
package/docs/agent-notes/bus.md
CHANGED
|
@@ -14,10 +14,14 @@ Scope: delivery, digests and condensation, reply addressing, priority and limits
|
|
|
14
14
|
- A reply is addressed, never broadcast. An adapter that answers a delivery passes `to: replyAudience(envs)`; anything else with an `inReplyTo` inherits that envelope's sender. Leaving `to` empty fans the message out to every peer.
|
|
15
15
|
- `digest` is not a peer: addressing a reply at the envelopes the peer was handed sends it nowhere once a delivery was condensed. The bus resolves `digest` back through `lastDelivery.originals`; anything else that reads a reply's `to` has to do the same.
|
|
16
16
|
- A pull-only peer (a Claude session without channel pushes or Kimi in its own TUI) is never drained; `Bus.pull` hands it what one push would take. Drain and pull share `held()` (recovery, an uncertain delivery, any pause, the lifecycle `deliveryHeld` fence) and `remember()` (so `reply_to` resolves), and a drain rechecks `deliverable()` after condensing because such a session can take the peer meanwhile. A pull is journaled `completed` in the same transaction as the bus snapshot, never `accepted`; a failed one puts back only that peer's queue and preface and never reloads the snapshot.
|
|
17
|
+
- Record exact task-offer reads only through `DeliveryJournal.completeDelivered` on an active-fenced adapter completion, correlated reply or actual pull, atomically with completion. Capture original offers before terminal pruning and record their ids, never condensed ids; accepted receipts, generic transitions, operator/hub dispositions and restored completed rows are not read evidence.
|
|
17
18
|
- The `onImportantQueued` nudge for a pull-only peer (#398) is advisory: it never dequeues, steers, journals or settles, and a throw from it never stops an enqueue.
|
|
18
19
|
- Merge recall and restored prefaces through `mergePrefaces`/`uniqueMemoryLines`; preserve distinct context and new notes, deduplicate memory identities, and keep colliding short prefixes distinct. Use `recallDisplayText`/`recallMemoryLines` before display caps: suppress only matching automatic approval outcomes, retain nonempty rejection details, preserve id headers and complete-word excerpts, and keep token trimming at line boundaries. Keep these changes display-only.
|
|
19
20
|
- Observe memory rendering from final `out`, not `originals`, and suppress telemetry when either contains private envelopes. A pull emits rendered/delivered observations only after its journal transaction commits; observer exceptions must never change delivery settlement.
|
|
21
|
+
- Classify automatic held-row completion only through `supersededDeliveryReason`: every original must be a hub presence or a provably moot hub task/review notice. Unknown/live/mixed rows stay held; keep `deliveryTaskContext` display-only. Tag only current-owner notices as owner audience; leave former-owner withdrawals untagged until the task closes. For cancelled tasks, settle earlier workflow notices but retain the stop notice whose `refs.taskCancelled` matches the cancellation revision. Preserve the requested-stop exclusion in `daemon.md`. Record the hub actor through `resolveDelivery`, restoring presence originals through `restorePreface` only for hub completion (person completion stays consumed); run on hold entry, restore, recovery release and board changes, never replay uncertain work. List every hold once in status, console notices and route explanations (#434).
|
|
20
22
|
- `resolveDelivery` mutates queues in place; a refused or failed resolution puts back only that peer's queue and preface and keeps every pause. Never reload a snapshot on a live bus. Keep the selected delivery id and journal revision fixed in console row actions; retry/discard/completed never change a task role or cancel a native turn.
|
|
23
|
+
- Do not offer recipient retry to delivery-only local/ACP transports or pass ordinary messages through their hold; their hints direct the person to resolve. Keep current-adapter refusal authoritative and the ephemeral MCP exposure marker advisory; pull-only Kimi TUI retains retry.
|
|
24
|
+
- Route peer retry only through `retryDelivery`: scope explicit-retry history by peer and immutable original ids across all grouped parents, commit monotone consumed-proof inheritance for every grouped non-context original with the checkpoint while keeping resolution audit rows unchanged; exclude hub `presence` originals from every retry proof, warning, inheritance and unknown-marking path, preserve unknown imported lineage fences without disabling fresh work, and admit busy-peer consent only to requeue its own `needs_review` row. Decorate rendered clones after condensation/pull/steer, never originals; reserve the shared journal body cap for the warning and an explicit Unicode-safe cut marker. Keep held hints bounded, body-free and advisory; metadata failure never changes a saved tool result or refusal class (#434).
|
|
21
25
|
- `restore` takes queued work from the journal, never from the committed snapshot once the journal has state (an empty journal, revision 0, is seeded from the commit): from the commit only an empty queue key is carried over, for an offline peer whose key no delivery ever persisted (#234). Never resurrect a non-empty queue from it.
|
|
22
26
|
- The journal's owner check (`rejectLiveOwner` in `delivery-journal.ts`) judges the manifest pid with `processLiveness` and its `pidSignature`, never a bare probe (rule: `daemon.md`).
|
|
23
27
|
- A hub-native peer (Pi, the local worker) does not get to call its own message `important`: `capPriority` caps it unless the delivery it answers held an `important` envelope addressed to it. Check the delivery, not `replyParent`, which ties on hop and takes the later item. Do not bypass it by setting `priority` in the adapter.
|
|
@@ -19,12 +19,15 @@ Scope: the operator console, control WS and its protocol, state files, the dashb
|
|
|
19
19
|
- Close 4000 is the one close that ends on its own, so it is not in `TERMINAL_CLOSES`: the session stands by and reconnects only once `status.json` reports the peer offline and not `claiming`. One exception (#205, `peerHeld` in `claude-channel.ts`): a session with channel pushes also reconnects when the holder is reported `toolsOnly` and not `claiming`, and takes the peer; the daemon refuses the reverse with 4000. Reconnecting blind would evict whoever holds the id now, and the two would trade it forever. `claim()` happens at hello and `attach()` only after the preface, so the peer reads as offline in between: the daemon writes the status file at the claim and the flag covers that window.
|
|
20
20
|
- Adding a native peer requires testing the command emitted by the actual recovery driver, not only its inspection or launch helpers. Never let a generic non-Codex branch treat a new peer as Claude.
|
|
21
21
|
- Cross-version recovery must use the authenticated source protocol for prepare/commit/abort and the target protocol after startup. Prove the transition against a real prior release before claiming compatibility.
|
|
22
|
+
- Preserve `task_cancel` target-feature preflight before source holds, capture or commit. Reuse stored target features only after verifying the same retained root and digest; legacy receipts still capable of commit must obtain feature proof. Do not apply pre-commit compatibility checks to sources already past commit.
|
|
23
|
+
- Resume a prepared `commitSent` source that is unavailable or database-busy inside the existing bounded shutdown poll; never re-send commit, re-prepare or close terminals again on that path. Require confirmed `stopped` before target startup, refuse a replacement instance, and retain the prepared receipt on timeout.
|
|
24
|
+
- Keep restoration receipts explicitly tagged as pending, waiting with origin/binding, done with binding, or failed. Project waiting origins as `waiting:pending` and `waiting:failed`; preserve the chosen binding and origin across interruption instead of inferring completion from an object.
|
|
22
25
|
- A zero-turn Claude session has no transcript, so it can never be resumed: every identity gate that compares session ids (restore, coordinator verify, daemon readiness) must tolerate a fresh session while the transcript is absent and stay strict the moment one exists. The commit snapshot records `sessionPersisted` for the restored daemon, and snapshots too old to have it are re-derived from disk. Never treat "session id changed" as proof of a lost conversation without checking the transcript first.
|
|
23
26
|
- The terminal-recovery launcher signature is the shared pinned `processSignature` (`src/pi/process-signature.ts`): a record written by one CLI invocation must compare equal when a later invocation re-reads the live launcher under another TZ/LC_ALL (#177). In-process `process.env` mutation does not reach Bun.spawnSync's default child environment, so cross-environment regressions are tested with real subprocesses. A row written by 0.12.12 or older carries the unpinned signature, which `launcherState` also compares (#228). A launch-record row that fails validation is unknown for the peer it may belong to and is written back unchanged, never filtered out (#228).
|
|
24
27
|
- Judge every recorded owner pid (hub manifest, registry claim, recovery runner, manager owner, launcher record) with `processLiveness` in `src/pi/process-signature.ts`, never a bare `process.kill(pid, 0)`: after a reboot a recorded pid can belong to another process, even one we may not signal, and the bare probe wedged recovery and `ahub up` (#226). A writer records `processSignature(process.pid)` beside its pid; a registry claim stores it as `<instance id> <signature>` because an older daemon's claim rewrites the pid but not that column. Records without a signature keep the bare-pid answer; unknown is never gone.
|
|
25
28
|
- A restored daemon accepts a changed native session id (Kimi and local aside: they restart as fresh workers) in two ways only: the #64 rule for a Claude session that never persisted a transcript, and the operation-fenced `recovery-waivers.json`, which the coordinator writes wherever it accepts a session other than the planned one: a reconnect-only Claude (#206), an operator-chosen fresh session, the plan's `freshStart` of a Codex thread the hub saw start with no turn, or a zero-turn Claude it accepted (#215). Never waive on any other evidence. Re-preparation after an expired lease keeps every effect receipt, and `restored:<peer>` = `failed` never counts as restored. Judge a restoration launcher by its `terminal-recovery.json` record and process signature (and a `terminal_handle_stale` answer), never by the terminal's exit; an unreadable record is unknown, never "none".
|
|
26
|
-
- A target that stopped after it started is restarted only through `recordRestart` (`src/cli/upgrade.ts`), recorded before the new one starts and at most once per project per resume: each done `restored:<peer>` becomes `retired:<peer>`, whose terminal is closed (`closedRetired:<peer>`) or found absent before that peer is relaunched, and is never revalidated against the new instance. Launcher evidence is read for every instance in `restarts`, and a session attached without an id is unknown, never gone (#225).
|
|
27
|
-
- After a managed terminal is created, persist its binding before waiting up to `RECONNECT_WAIT_MS` for authenticated attachment to the expected target instance, operation and conversation (#414). Resume waits on the saved binding without creating another terminal. Timeout keeps the receipt blocked and records only terminal/hub metadata; a last native connect attempt that was never recorded is unknown, never inferred from terminal readiness or offline state. Final identity and preservation verification stays strict.
|
|
29
|
+
- A target that stopped after it started is restarted only through `recordRestart` (`src/cli/upgrade.ts`), recorded before the new one starts and at most once per project per resume: each done or waiting `restored:<peer>` binding becomes `retired:<peer>`, whose terminal is closed (`closedRetired:<peer>`) or found absent before that peer is relaunched, and is never revalidated against the new instance. Launcher evidence is read for every instance in `restarts`, and a session attached without an id is unknown, never gone (#225).
|
|
30
|
+
- After a managed terminal is created, persist its binding before waiting up to `RECONNECT_WAIT_MS` for authenticated attachment to the expected target instance, operation and conversation (#414). Resume waits on the saved binding without creating another terminal. Count only attached, non-offline session ids; when the chosen terminal has no current launch record, a confirmed-ended row for another handle or an id-less attachment retains the bounded wait after older-launcher checks. A late current record must match the saved terminal; unknown or live replacement evidence still blocks. Timeout keeps the receipt blocked and records only terminal/hub metadata; a last native connect attempt that was never recorded is unknown, never inferred from terminal readiness or offline state. Final identity and preservation verification stays strict.
|
|
28
31
|
- An operation receipt stays `schema: 1`. Only `abandoned()` writes 2, on an operation with a recorded `disposition` whose coordinator predates #215: in the same write as the disposition, or, for a disposition 0.12.20 recorded at 1, by the next command that holds the runner claim. `validateReceipt` accepts 2 only with a disposition (#227). Never write 2 on an operation that can still be resumed.
|
|
29
32
|
- Three checks read another release's source text for an exact line: `coordinatorCurrent` (`export async function disposeRecovery` in `src/cli/upgrade.ts`), `targetReadsWaivers` (`export function readRecoveryWaivers` in `src/hub/restart.ts`) and `coordinatorRestarts` (`export function recordRestart` in `src/cli/upgrade.ts`). Renaming, moving or un-exporting one makes this release read as an older one: keep those lines until a capability list replaces the checks.
|
|
30
33
|
- The interactive screens (`src/cli/upgrade-interactive.ts`, #272) change an operation only by running an existing command (`recovery resume|abort|dispose`, `reset`) through `io.run`, and build their menu from `nextChoices`, whose text is `nextActions`: never call `abortRecovery`, `disposeRecovery` or a driver from a screen, and never offer a choice `next` does not have. The one addition is `cancellableWait` (a runner still at `prepare` with no effect): read the receipt again at the key press, stop only a runner `signedRunner` names (a claim without a matching process signature is never signalled), then run `recovery abort`, which decides again. Agents are ended (`endPlannedPeer`) only before an operation holds the lock, and only after the lock, the hub instance, the attached session and the terminal's handle and incarnation were read again: never on the plan as it was drawn. Ctrl+C leaves the screens and the terminal is not read after it; a prompt answers an interrupt with null, never text. What a hub says it waits for (`recovery.waiting`, the daemon's `blockers`) is shown, never decided on.
|
|
@@ -17,3 +17,5 @@ Scope: the hub-native local worker, its tools, path guard, denylist and seatbelt
|
|
|
17
17
|
- A tool that asks for approval passes its name to `ctx.permit`, and `write`/`edit` also the `guardPath` result, never the model's path string: also pass the original path separately through every permit wrapper; `ask-when-needed` grants only when both the original project-relative spelling and the real path avoid protected names through `grantablePath` (`src/hub/permission-mode.ts`). `bash` and mutating `git` pass no path. After the awaited approval `write`/`edit` run `guardPath` again and refuse a target that changed (#242).
|
|
18
18
|
|
|
19
19
|
- Honor the live `protect_instruction_files` policy in scoped grants for the three instruction names; keep reads, explicit approval and never-ask unchanged. Only the settings registry writes this machine-local policy (#323).
|
|
20
|
+
|
|
21
|
+
- For sandboxed task checks, use the opt-in hub-owned bounded container runner; never widen Seatbelt, expose credentials, mount host paths or fall back to a host command. Keep spec/check arguments and results out of capture.
|
|
@@ -8,6 +8,9 @@ Scope: the task flow, assignment, the state machine and the hub's MCP tools. Rea
|
|
|
8
8
|
- Role withdrawal matches the task id, role kind and owner-request header. Owner acceptance evidence must be that peer's accepted entry after the latest ownership event, never another owner's state or an earlier assignment span. Withdraw unread requests without inventing delivery evidence. Preserve the original former-owner stop notice after a superseding escalation, while suppressing stale success/decision tails.
|
|
9
9
|
- `assign()` never defaults to the task's current owner, or a decline can only come back to the decliner. A reservation (#207) is the same risk: the reserved owner goes first only through `blocked()`, and a decline or an escalation for reason `rejections` or `manual` records the owner it left in the history entry's `from`, which `excluded()` reads, so no later reroute hands the task back through its reservation.
|
|
10
10
|
- The state machine allows `in_progress -> approved` only for classes without a reviewer; `review()` checks `in_review` itself.
|
|
11
|
+
- Treat `cancelled` as closed through `isClosedTaskState`, but keep dependency release restricted to approval. Cancellation goes through `Tasks.cancel`, preserves the row and roles, clears its reservation/cohort, sends revision-bound stop notices and writes no outcome memory; never map it to approval or cancel a native turn or worktree. Planner cancellation stays limited to its own historically unaccepted proposed/backlog work; accepted work remains person-only.
|
|
12
|
+
- Capture `TaskOffer.pullOnly` and the exact offer envelope id at publication. Keep unread-offer attention independent of attachment and restart until acceptance, decline, supersession or `offerRead` evidence; never replace that evidence with a generic inbox timestamp or completion state.
|
|
13
|
+
- Use the daemon's settled role map for planner authority and notice recipients. An explicit planner designation is exclusive; automatic fallback remains runtime-only. Keep ready-unassigned sweep admission consistent with person-unassignment suppression, planner-pull reservation/WIP limits and ordinary routing guards; persist each ladder step before its notice.
|
|
11
14
|
- `.agenthub/routing.local.toml` (#269) may hold only `stay_switch` and per-class `peers`, `escalate_to`, `route` and `pi_backend` (`checkOverlay` in `src/hub/routing.ts`): never widen it to targets, routes, signals or constraints, which stay in the hand-written `routing.toml`. `parseRouting` is the one merge, and `assign()` reads `routing.sources` only for its trace line.
|
|
12
15
|
- Conductor authority requires the explicit unique role before capability checks. The only exceptions run before that check in `Conductor.execute` and stay task-scoped: a task's current owner and reviewer read it with `hub_task_show` (#208), and its proposer redirects it with `hub_task_assign` while nobody ever accepted it and no person moved it (#207). Removing them strands reviewers that missed a review request. Assignments preserve the acting peer. A peer releases only its own conductor hold; operator release and manual, quota and recovery holds remain separate paths.
|
|
13
16
|
- The PII screen (#198) runs in `propose` before anything else reads the task (no board row, envelope, triage or brief before its verdict), and `unknown` is PII. A call that screens free text (`done`, `review`, `remember`) screens only after its own checks pass, and `done` and `review` run them again after the awaited screen, because the task can change meanwhile. A history entry marked `withheld` stays withheld in public views, completed notices and review requests, whatever `nameable()` says; `ahub ask` shows it only on campus, like a note that matches a PII pattern.
|
|
@@ -28,3 +31,5 @@ Scope: the task flow, assignment, the state machine and the hub's MCP tools. Rea
|
|
|
28
31
|
- Compose structured `hub_remember` fail fields through `composeRememberText` before screening or writes; reject over 4000 UTF-8 bytes without truncation. Treat plan-fail matches as screened advisory priority only, never a state-transition guard; skip all plan-memory work for PII tasks.
|
|
29
32
|
|
|
30
33
|
- Keep candidate production in Tasks: screen review/correction payloads and current task/turn privacy before CandidateStore writes; recheck after asynchronous screening. Never make candidate failures roll back a saved review, or let a peer accept a candidate. Keep candidate tool arguments/results out of capture.
|
|
34
|
+
|
|
35
|
+
- Feed the same current spec/test capability map into every `assign()` path, explicit nomination and reservation. Apply these capability refusals only to non-PII owner admission, preserving reviewer and on-prem PII routing exemptions; refuse a missing required capability before a manual owner assignment write. Bind spec/check authority and result delivery to the current task, owner, peer generation and privacy policy.
|
|
@@ -5,15 +5,18 @@ Scope: tests, fakes and the test gate. Read before adding or changing a test or
|
|
|
5
5
|
- Tests that are not about batching build the bus with `batchMs: 0`; with the default 15 s window a lone status envelope looks like a lost message.
|
|
6
6
|
- In Bun 1.3.14 a test timeout that fires while `Bun.spawnSync` runs can start the next test inside spawnSync's own event loop, where another spawnSync then spins at full CPU for good (trigger not pinned down; see README). Bun 1.4.2 still runs the next test inside the outer spawnSync's event loop. `scripts/check.sh` runs tests with a 20 s timeout and under `scripts/hang-watch.sh`; a test that spawns and reads the process table gets a timeout of its own.
|
|
7
7
|
- The Switchyard sidecar, sandboxed commands and the MLX server get a fixed environment (`PATH`, `HOME` and their own keys), so test knobs for their fakes travel in a wrapper script or argv, not in `process.env`; native peer children inherit the hub's environment minus the agent markers (`peerChildEnv`).
|
|
8
|
-
- Bind agent identity markers explicitly in native/CLI fixture children. The full gate starts the test runner without inherited agent markers and without an `ahub claude` session's hub variables (`AGENTHUB_PROJECT_DIR`, `AGENTHUB_STATE_DIR`, `AGENTHUB_INSTANCE_ID`, `AGENTHUB_LAUNCH_ID`); a new variable a native session exports and a fixture child reads joins that `env -u` list in `scripts/check.sh`. Never weaken production marker detection to make them pass.
|
|
8
|
+
- Bind agent identity markers explicitly in native/CLI fixture children. The full gate starts the test runner without inherited agent markers (including `AGENTHUB_DELIVERY_ONLY`) and without an `ahub claude` session's hub variables (`AGENTHUB_PROJECT_DIR`, `AGENTHUB_STATE_DIR`, `AGENTHUB_INSTANCE_ID`, `AGENTHUB_LAUNCH_ID`); a new variable a native session exports and a fixture child reads joins that `env -u` list in `scripts/check.sh`. Never weaken production marker detection to make them pass.
|
|
9
9
|
- `bunfig.toml` preloads `test/hub-home.ts`, which first clears inherited `AMEM_HOME` and gives every test run (the gate and `bun test <file>` alike) a temp `AGENTHUB_HOME` unless one is set; scoped tests may set their own `AMEM_HOME` after preload. Hub memory (#258) is on with any project config, and no test may write the person's `~/.agenthub`. Do not remove it; a test that needs its own home sets and restores the variable.
|
|
10
10
|
- A free-port probe binds `hostname: "127.0.0.1"`, matching the loopback server that takes the port (#232).
|
|
11
11
|
- `ahub upgrade` without `--to` asks the registry (`npm view`) and hands a target newer than the CLI to `bun x` (#272): a test that reaches either puts a fake `npm` first on `PATH` and a recording stand-in for `process.execPath`, as `test/upgrade-cli.test.ts` does. The interactive screens are tested through a scripted `ScreenIO`; a CLI test that needs them marks `process.stdin` and `process.stdout` as terminals in a wrapper script.
|
|
12
12
|
- Cross-process fixtures wait for the consuming client to process its handshake (the channel connected diagnostic), not merely the daemon's attached/idle state. Deadline-routing fixtures hold and release responses at the fallback decision; do not place a fixed sleep between deadline fractions and assume scheduler headroom (#287). Receipt-order fixtures use the normal watchdog for ordinary I/O, trigger expiry after observed native acceptance, and await a consumed transport barrier before asserting on late results.
|
|
13
13
|
- A bounded polling wait must assert its condition after the last attempt, or document why giving up is intentional. Append-only event histories wait for a correlated closing event, not removal of the opening event. Before changing a slow wait, identify the unreached state and repair its cause (#296).
|
|
14
14
|
- A request that a test expects a stop or shutdown to cut gets its rejection handler where the request is created, never after the awaited teardown: a late `catch` races the reset and the run fails on an unhandled rejection.
|
|
15
|
-
- Run `bun scripts/seeded-check.ts` before reporting the seeded-guard gate complete. Keep the `scripts/seeds.json` cases sequential; require the same named test green before its seeded assertion fails. Seed rot, survivors, setup/compiler failures, timeout/watchdog termination and process leaks fail the gate. Never run the full seed runner from a unit test or mutate the source checkout; inspect preserved failed fixtures before removing them. CI runs
|
|
15
|
+
- Run `bun scripts/seeded-check.ts` before reporting the seeded-guard gate complete. Keep the `scripts/seeds.json` cases sequential; require the same named test green before its seeded assertion fails. Seed rot, survivors, setup/compiler failures, timeout/watchdog termination and process leaks fail the gate. Never run the full seed runner from a unit test or mutate the source checkout; inspect preserved failed fixtures before removing them. CI runs it as four sequential Linux shards (`--shard i/4`) beside the ordinary check, separately from `scripts/check.sh`; the required `seeded guards` job passes only when every shard passed. Keep that job name: branch protection and `scripts/ci-gates.mjs` read it (#457).
|
|
16
16
|
|
|
17
17
|
- `scripts/check.sh` holds the repo's heavy-job slot (`<git common dir>/ahub-heavy.lock`, #398) for the whole run, so a test never runs the real gate; `test/check-lock.test.ts` runs a copy in a scratch repo.
|
|
18
18
|
- The whole-suite watchdog is `AHUB_CHECK_HANG_S` (default in `scripts/check.sh`, hosted macOS value in `.github/workflows/check.yml`; #378, macOS CI hit it while tests still passed): raise it only when the suite was still progressing at the cutoff, never for a hung test, and keep the per-test 20 s timeout.
|
|
19
19
|
- A seed's named test must run on Linux, where the seeded job runs: a darwin-only test reports no result there and fails the job (#382). Cover a macOS-only protection with its regression test instead.
|
|
20
|
+
|
|
21
|
+
- Keep CI's Bun version sourced from `.bun-version` through the pinned setup-bun action; update the version file rather than adding per-job version literals.
|
|
22
|
+
- Release verification requires both OS checks and the aggregate `seeded guards` success for an identical tree, a tag matching `package.json` on `origin/main`, and fresh ancestor-bound documentation stamps. Preserve the separate npm OIDC publish job and GitHub Release write job; neither job gets the other's credential authority.
|
package/docs/memory.md
CHANGED
|
@@ -20,7 +20,7 @@ A running daemon keeps its original binding. Explicit checks at hub operation en
|
|
|
20
20
|
|
|
21
21
|
Candidate/counter data stays at `M/candidates.db`, independently of the selected note profile, using the package's explicit sidecar home convention. It is not copied into `G`, migrated or synced. The hub fences sidecar producers with the note-profile binding. Standalone `amem review` still refuses a selected generation; this integration does not add generation candidate acceptance or dashboard acceptance.
|
|
22
22
|
|
|
23
|
-
Source and synthetic fixture checks do not authorize migration of the person's memory home. Before real migration, every hub sharing the memory home must run 0.12.30. Real rollout still needs separately approved installation, matching live package/root/profile/selector bindings, synthetic cross-write and prune readbacks, and a supported quiesce/close/reopen sequence before separately confirmed real migration. 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. Real account/device sync, native capture and live memory receipts remain distinct acceptance legs. See [agent-mem migration and prune](https://github.com/STAIxBWLB/agent-mem#generation-migration-and-exact-entry-prune) for the person CLI and recovery limits.
|
|
23
|
+
Source and synthetic fixture checks do not authorize migration of the person's memory home. Before real migration, every hub sharing the memory home must run 0.12.30 or later. Real rollout still needs separately approved installation, matching live package/root/profile/selector bindings, synthetic cross-write and prune readbacks, and a supported quiesce/close/reopen sequence before separately confirmed real migration. 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. Real account/device sync, native capture and live memory receipts remain distinct acceptance legs. See [agent-mem migration and prune](https://github.com/STAIxBWLB/agent-mem#generation-migration-and-exact-entry-prune) for the person CLI and recovery limits.
|
|
24
24
|
|
|
25
25
|
For a standalone CLI refusal, inspect the selector and generation state and run `ahub memory profile-check`. If deliberately abandoning the selected generation, use the person-only `amem migrate --deactivate` recovery path; a CLI error does not itself require restarting a hub.
|
|
26
26
|
|
package/docs/operations.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Operations guide
|
|
2
2
|
|
|
3
|
-
This guide describes ahub 0.12.
|
|
3
|
+
This guide describes ahub 0.12.31 and control protocol 16. Live verification
|
|
4
4
|
results and remaining prerequisites are recorded separately in [the smoke ledger](smoke.md).
|
|
5
5
|
|
|
6
6
|
## Agent-operated live verification
|
|
@@ -123,8 +123,13 @@ adds no timer, network request or writable settings path.
|
|
|
123
123
|
Tabs change with the digits 1 to 5 or with Left and Right (wrapping at both
|
|
124
124
|
ends), never while a command is being edited or a choice is open; under a
|
|
125
125
|
confirmation an arrow dismisses it like any key but y, without moving a tab. A pasted
|
|
126
|
-
chunk can only edit the command line, but a read that holds nothing but arrow
|
|
127
|
-
sequences is that many key presses, so a held key repeats its
|
|
126
|
+
chunk can only edit the command line, but a read that holds nothing but arrow or
|
|
127
|
+
Home/End sequences is that many key presses, so a held key repeats its move. Home
|
|
128
|
+
or `<` jumps to a panel's first row and End or `>` to its last; the Events tab
|
|
129
|
+
follows new events while the last row is selected and stays on a row you moved to.
|
|
130
|
+
`w` opens the dashboard and `o` the pet window; `:ui --all` and `:pet --window --close`
|
|
131
|
+
work on the command line too. In the Peers tab the planner's row reads `(planner)`, and
|
|
132
|
+
`l` then `y` makes the selected peer the planner (`ahub settings set planner <peer>`). In the Events
|
|
128
133
|
tab a row's header line is tokenized and coloured exactly as the same event in
|
|
129
134
|
the stream; only the header is tab-flattened before tokenizing. Body lines retain
|
|
130
135
|
the previous rendering and stay plain, as does command output; colour never changes
|
|
@@ -189,7 +194,27 @@ In Tasks, `a` assigns the owner in ordinary open states and the reviewer in
|
|
|
189
194
|
the corresponding role, and `r` reviews only in `in_review`. In Queue, `r`
|
|
190
195
|
prefills `discard` for a queued row and `retry` for a needs_review row, with the
|
|
191
196
|
action still editable before confirmation. `completed` is never the default.
|
|
192
|
-
|
|
197
|
+
Status, console notices and `route explain` show every held row with its id, sender, kind and age. The hub completes rows made entirely of superseded hub workflow notices or presence items, recording an ids-only reason and the hub actor. Mixed messages, live task notices and unknown references remain held. A Claude session without channel support safely returns unseen pushes for `hub_inbox`; a thrown notification write remains uncertain.
|
|
198
|
+
|
|
199
|
+
Claude channel/pull sessions, Codex and Pi may call `hub_delivery_retry { delivery_id }` for their own
|
|
200
|
+
`needs_review` row once. Its tool results show held-row count, ids, senders,
|
|
201
|
+
kinds and age, never message bodies or task text (up to 32 rows/4 KiB, with an
|
|
202
|
+
explicit truncation notice). The redelivery starts with a fixed warning that
|
|
203
|
+
the earlier attempt is uncertain and its effects must be checked before acting.
|
|
204
|
+
The warning fits within the existing journal body limit. If needed, only the rendered copy is clipped at a Unicode character boundary and ends with an explicit cut marker; the original message is retained. Consumed-retry proof follows every coalesced original atomically with a successful checkpoint, surviving safe failure, stale removal, pruning and restart.
|
|
205
|
+
|
|
206
|
+
Any earlier explicit retry in the same recipient's lineage, including a person's
|
|
207
|
+
retry, leaves a later hold for the person. A busy peer's request only requeues
|
|
208
|
+
the originals; delivery waits for idle and retains all pauses and recovery holds.
|
|
209
|
+
Hub presence prefaces are mutable context, so they do not consume or inherit a
|
|
210
|
+
message's retry allowance and never receive the uncertain-retry warning.
|
|
211
|
+
The tool cannot complete or discard a row. If a recovery snapshot lacks retry
|
|
212
|
+
history, or older pruned retry records cannot be mapped, the affected message
|
|
213
|
+
lineages require a person; unrelated new messages retain the one-retry option.
|
|
214
|
+
|
|
215
|
+
The local worker and headless ACP peers, including Jcode, receive tools only inside a delivered turn. A hold prevents that turn, so these delivery-only transports do not offer recipient retry; their held hints ask the person to resolve the row. Ordinary messages stay queued. This restriction follows the current transport, not the vendor name: Kimi TUI remains pull-only and can request its one retry.
|
|
216
|
+
|
|
217
|
+
Every console resolution needs a reason. Queue `discard` removes queued originals or
|
|
193
218
|
settles a needs_review receipt; it never cancels a task or native turn.
|
|
194
219
|
|
|
195
220
|
`ahub task unassign <id> [--role owner|reviewer] [--revision N]` is the terminal
|
|
@@ -464,6 +489,26 @@ Tool-call receipts survive daemon restart; an interrupted operation with an
|
|
|
464
489
|
unknown outcome must be reconciled before repeating it. Cancelling a Pi turn
|
|
465
490
|
does not automatically hand its task to a cloud peer.
|
|
466
491
|
|
|
492
|
+
For assigned, non-private work, `hub_task_spec` reads the named GitHub issues
|
|
493
|
+
through the hub's authenticated, bounded read path. `hub_check_start` runs an
|
|
494
|
+
exact Git ref's permitted tests or typecheck in the opt-in isolated container
|
|
495
|
+
runner (`checks.runner: "container"`); `hub_check_result` and `hub_check_cancel`
|
|
496
|
+
read or cancel that owned run. Missing spec/check capability refuses the
|
|
497
|
+
assignment early; it never grants host commands, credentials or broader sandbox
|
|
498
|
+
access. Receipts distinguish exact source/tree/lockfile, platform, exit and
|
|
499
|
+
uncertain or cancelled outcomes. See [bounded spec and check access](security.md#bounded-task-specs-and-isolated-checks-418)
|
|
500
|
+
for the authorization and resource bounds.
|
|
501
|
+
|
|
502
|
+
Retention bounds inactive valid check receipts to 200 records and the newest 20
|
|
503
|
+
full outputs, excluding active runs. Full output is also consumed by the owner
|
|
504
|
+
result read or expires after 24 hours.
|
|
505
|
+
Malformed or unreadable receipts are a retention exception: their receipt bytes,
|
|
506
|
+
output and staging stay for inspection, with ID-only warnings separate from
|
|
507
|
+
unknown container-owner warnings. Maintenance skips them while continuing valid
|
|
508
|
+
retention; it never deletes an unknown container. See the security contract for
|
|
509
|
+
the same-user parent-swap cleanup limitation. These source guarantees do not
|
|
510
|
+
establish the separate native macOS acceptance leg.
|
|
511
|
+
|
|
467
512
|
The `mlx/fast` alias now defaults to an externally managed Ollama MLX backend.
|
|
468
513
|
Install and start Ollama separately, with `OLLAMA_NO_CLOUD=1`,
|
|
469
514
|
`OLLAMA_NUM_PARALLEL=1`, `OLLAMA_MAX_LOADED_MODELS=1`, and a finite
|
|
@@ -559,7 +604,8 @@ PID-name matching. See the operations guide and the
|
|
|
559
604
|
|
|
560
605
|
## Install and start
|
|
561
606
|
|
|
562
|
-
Use Bun 1.4.2 or newer.
|
|
607
|
+
Use Bun 1.4.2 or newer. Source checks and CI use the version pinned in
|
|
608
|
+
`.bun-version` (currently 1.4.2). Install the released package and install its Claude
|
|
563
609
|
channel plugin:
|
|
564
610
|
|
|
565
611
|
```bash
|
|
@@ -923,7 +969,7 @@ The daemon checks its selector at hub operation entry and before candidate/count
|
|
|
923
969
|
|
|
924
970
|
Run `ahub memory profile-check [--json]` from the person's terminal for the read-only preflight. It identifies live registry owners by signed process identity and authenticated daemon replies, then reports their loaded memory package and bound home/profile. The receipt names the current `AGENTHUB_HOME` registry scope; zero results establish no live daemon in that inventory, not system-wide process absence. Inventory and check separate custom registries too when they share `AMEM_HOME`. A missing or unreadable runtime receipt never counts as a different home or permission to migrate.
|
|
925
971
|
|
|
926
|
-
Before real migration, first upgrade every hub sharing the home to 0.12.30. Obtain positive ready or unbound/quiesced receipts in every relevant registry; then quiesce consumers and close bound handles before changing the selector. A matching ready handle proves compatibility but is still an open handle. Verify synthetic cross-writes before the separately approved real migration, then reopen through the supported session-preserving lifecycle afterward. Merely installing this release does not authorize migration or provide live capture/device-sync evidence.
|
|
972
|
+
Before real migration, first upgrade every hub sharing the home to 0.12.30 or later. Obtain positive ready or unbound/quiesced receipts in every relevant registry; then quiesce consumers and close bound handles before changing the selector. A matching ready handle proves compatibility but is still an open handle. Verify synthetic cross-writes before the separately approved real migration, then reopen through the supported session-preserving lifecycle afterward. Merely installing this release does not authorize migration or provide live capture/device-sync evidence.
|
|
927
973
|
|
|
928
974
|
Managed agents read through `hub_memory_search`, `hub_memory_show` and `hub_memory_graph`, with the server's project identity, the `memory_read` capability and current privacy screening. They cannot supply another project; private turns are refused. The tools bound UTF-8 input/output, screen before counts and truncation, and exclude their arguments/results from hub-managed capture. `hub_memory_correct` has its own `memory_correct` capability and records a screened correction candidate, not a note change. See [the complete memory contract](memory.md) for caps and refusal semantics.
|
|
929
975
|
|
|
@@ -1412,6 +1458,7 @@ ahub ui --settings # dashboard with a 15-minute settings session
|
|
|
1412
1458
|
| Start | `pi.auto_start` | `config.local.json` | next hub start |
|
|
1413
1459
|
| Routing | `routing.stay_switch`, `routing.classes.<class>.peers`, `.escalate_to`, `.route`, `.pi_backend` | `routing.local.toml` | at once |
|
|
1414
1460
|
| Switches | `research.enabled`, `approvals.notify`, `snapshots.enabled`, `coordination` | `config.local.json` | next hub start |
|
|
1461
|
+
| Roles | `planner` (the one peer that plans) | `config.local.json` | at once |
|
|
1415
1462
|
|
|
1416
1463
|
- Writes go only to `.agenthub/config.local.json` and `.agenthub/routing.local.toml`,
|
|
1417
1464
|
the machine-local files (`ahub init` ignores both in git). The shared
|
|
@@ -1505,8 +1552,10 @@ The configured `kimi_cmd` must be a single executable or end in exactly `acp`;
|
|
|
1505
1552
|
the TUI uses the executable or drops that final word. Other wrappers are refused
|
|
1506
1553
|
with the headless command rather than guessed.
|
|
1507
1554
|
|
|
1508
|
-
The TUI is pull-only. Its model reads `hub_inbox` at the start of work
|
|
1509
|
-
reporting, and shares results
|
|
1555
|
+
The TUI is pull-only. Its model reads `hub_inbox` at the start of work, between
|
|
1556
|
+
steps of longer work and before reporting, and shares results, and mid-work
|
|
1557
|
+
blockers or changed contracts, explicitly with `hub_send` addressed with `to`
|
|
1558
|
+
(progress-only notes `[FYI]`). Status, the console and
|
|
1510
1559
|
the dashboard show `pull-only`, the waiting count and the last inbox read. Messages
|
|
1511
1560
|
and important markers do not push or interrupt it. There is no hub busy state,
|
|
1512
1561
|
watchdog, console approval, hub permission mode, context reading, automatic quota
|
|
@@ -1710,6 +1759,28 @@ so a restarted hub never launches beside a survivor. A hub whose project root
|
|
|
1710
1759
|
or state directory was deleted stops itself within about 10 seconds; the
|
|
1711
1760
|
dashboard manager does the same when its home directory vanishes.
|
|
1712
1761
|
|
|
1762
|
+
## The planner (#455)
|
|
1763
|
+
|
|
1764
|
+
One peer plans: it proposes and splits tasks, grooms the backlog and gets the
|
|
1765
|
+
backlog and sweep notices. `ahub status` prints it with its source, the
|
|
1766
|
+
dashboard's Agents view shows a Planner badge, and the console marks its row.
|
|
1767
|
+
|
|
1768
|
+
- `setting`: `planner` in `.agenthub/config.json` or `config.local.json` (the
|
|
1769
|
+
machine's file wins). That peer is the only planner; every other peer loses
|
|
1770
|
+
the role. It is one of `claude`, `codex`, `kimi`, `qwen` or `jcode`: the
|
|
1771
|
+
hub-sandboxed `pi` and `local` never plan.
|
|
1772
|
+
- `roles`: with no `planner` key, the `roles` planners stand. That is `claude`
|
|
1773
|
+
by default.
|
|
1774
|
+
- `automatic`: when no rostered peer holds the role, the hub gives it to the
|
|
1775
|
+
first rostered peer of that list. It recomputes this at start and after
|
|
1776
|
+
each roster change, and writes nothing to disk.
|
|
1777
|
+
|
|
1778
|
+
Change it with `ahub settings set planner codex`, the dashboard Settings row
|
|
1779
|
+
(a settings session, `ahub ui --settings`) or `l` in the console. Planning
|
|
1780
|
+
authority and the backlog notices move at once. The new planner's role text
|
|
1781
|
+
updates at its next start. `ahub settings undo` puts the previous planner
|
|
1782
|
+
back. Agents cannot change it.
|
|
1783
|
+
|
|
1713
1784
|
## Resetting a project's hub
|
|
1714
1785
|
|
|
1715
1786
|
`ahub reset` returns a project's hub to a clean state. Without `--yes` it is a
|
|
@@ -1842,21 +1913,21 @@ section is what they run.
|
|
|
1842
1913
|
|
|
1843
1914
|
Upgrade running projects with the target release's own coordinator. It accepts
|
|
1844
1915
|
a running source on control protocol 9 (0.6.x), 10 (0.7.0 through 0.12.0),
|
|
1845
|
-
11 (0.12.1 and 0.12.2), 12 (0.12.3), 13 (0.12.4 through 0.12.15), 14 (0.12.16), 15 (0.12.17 through 0.12.19) or 16 (0.12.20 through 0.12.
|
|
1916
|
+
11 (0.12.1 and 0.12.2), 12 (0.12.3), 13 (0.12.4 through 0.12.15), 14 (0.12.16), 15 (0.12.17 through 0.12.19) or 16 (0.12.20 through 0.12.31), and only
|
|
1846
1917
|
a target on its own protocol, so the target's coordinator fits every supported
|
|
1847
1918
|
source and carries every recovery fix released up to it. Protocol 8 and older
|
|
1848
1919
|
(0.5.x and earlier) are refused as `manual-bootstrap-required`. Run from the
|
|
1849
1920
|
project directory, without replacing the global CLI first:
|
|
1850
1921
|
|
|
1851
1922
|
```bash
|
|
1852
|
-
bunx --package @staix/agent-hub@0.12.
|
|
1853
|
-
bunx --package @staix/agent-hub@0.12.
|
|
1923
|
+
bunx --package @staix/agent-hub@0.12.31 ahub upgrade --to 0.12.31 --dry-run
|
|
1924
|
+
bunx --package @staix/agent-hub@0.12.31 ahub upgrade --to 0.12.31 --yes
|
|
1854
1925
|
```
|
|
1855
1926
|
|
|
1856
1927
|
| Running now | Coordinator to use |
|
|
1857
1928
|
| --- | --- |
|
|
1858
1929
|
| 0.6.x (protocol 9) | the target's, through `bunx` as above |
|
|
1859
|
-
| 0.7.0 through 0.12.0 (protocol 10), 0.12.1 and 0.12.2 (protocol 11), 0.12.3 (protocol 12), 0.12.4 through 0.12.15 (protocol 13), 0.12.16 (protocol 14), 0.12.17 through 0.12.19 (protocol 15), 0.12.20 through 0.12.
|
|
1930
|
+
| 0.7.0 through 0.12.0 (protocol 10), 0.12.1 and 0.12.2 (protocol 11), 0.12.3 (protocol 12), 0.12.4 through 0.12.15 (protocol 13), 0.12.16 (protocol 14), 0.12.17 through 0.12.19 (protocol 15), 0.12.20 through 0.12.31 (protocol 16) | the target's, through `bunx` as above |
|
|
1860
1931
|
| any supported source, with the installed CLI already at the target | `ahub upgrade` below, which is the same coordinator |
|
|
1861
1932
|
| 0.5.x or earlier (protocol 8 and older) | not supported: bootstrap by hand with the matching CLI |
|
|
1862
1933
|
|
|
@@ -1888,14 +1959,14 @@ projects first:
|
|
|
1888
1959
|
|
|
1889
1960
|
```bash
|
|
1890
1961
|
ahub restart --dry-run
|
|
1891
|
-
ahub upgrade --to 0.12.
|
|
1962
|
+
ahub upgrade --to 0.12.31 --dry-run
|
|
1892
1963
|
```
|
|
1893
1964
|
|
|
1894
1965
|
Apply only after reviewing the plan:
|
|
1895
1966
|
|
|
1896
1967
|
```bash
|
|
1897
1968
|
ahub restart --yes
|
|
1898
|
-
ahub upgrade --to 0.12.
|
|
1969
|
+
ahub upgrade --to 0.12.31 --yes
|
|
1899
1970
|
ahub recovery status [<operation-id>]
|
|
1900
1971
|
ahub recovery resume [<operation-id>]
|
|
1901
1972
|
ahub recovery abort [<operation-id>]
|
|
@@ -1962,7 +2033,9 @@ A lost commit or start reply is reconciled against the actual daemon identity,
|
|
|
1962
2033
|
package digest, terminal binding, and phase receipt. An uncertain terminal
|
|
1963
2034
|
creation is never repeated blindly. Recovery retains the exact-pinned first-party memory package with the preserved runtime, includes its identity and bytes in the digest, and refuses missing, symlinked or changed retained dependencies instead of resolving a mutable ancestor/global installation. It does not copy the full dependency tree.
|
|
1964
2035
|
|
|
1965
|
-
After creating a managed terminal, the coordinator saves its
|
|
2036
|
+
After creating a managed terminal, the coordinator saves its exact handle, incarnation and worktree before waiting up to 600 seconds (10 minutes) for authenticated attachment to the expected target hub and conversation. A pending or failed creation receipt also waits when the current target has a verified live launcher; its saved binding retains the pending/failed origin across interruption. An idle terminal alone is not attachment proof. Without a current launch record, a confirmed-ended row for another terminal and an attached session still reporting no id keep the chosen terminal waiting within the same bound; a late matching record continues that wait. Live replacement and unreadable records still block. Only non-offline session ids count, and older-instance launchers are checked before declaring a launch gone. Timeout retains the binding and diagnostic receipt; resume waits on that same binding rather than opening a duplicate.
|
|
2037
|
+
|
|
2038
|
+
The wait checks the selected launcher's signed identity on each poll. When that exact launcher exits and the target confirms no session or other live launcher, a pending-origin wait (including a new terminal) records failure and offers the failed-restoration choices, including fresh-session for Codex or Claude. A failed-origin wait returns to its existing retry path. A replacement terminal, missing or unreadable launcher identity, unreadable target or different attached conversation blocks without treating unknown as gone. Success clears the waiting origin and preserves exact terminal/session revalidation. A launcher from an older target instance still blocks without another terminal. The 10-minute limit matches terminal creation readiness; terminal idle can precede native resume and MCP handshake completion. The zero-turn Claude exception still applies only when no original transcript exists. If Claude shows its development-channel confirmation screen, confirm it in
|
|
1966
2039
|
the captured terminal, then run `ahub recovery resume <operation-id>`; resume must not open a duplicate terminal.
|
|
1967
2040
|
Kimi and local sessions may start fresh with preserved routing and task context.
|
|
1968
2041
|
A Claude session that never persisted a transcript (zero turns) also starts fresh:
|
|
@@ -2082,7 +2155,8 @@ or cancel and upgrade later.
|
|
|
2082
2155
|
its phase, step and error; `runner`, which says whether a runner process holds
|
|
2083
2156
|
the operation now (`running` with its pid, or `none`; `stale` marks a receipt
|
|
2084
2157
|
that says running with no runner behind it); each project's phase and effect
|
|
2085
|
-
receipts (`closed:<peer
|
|
2158
|
+
receipts (`closed:<peer>` as `done` or `pending`; `restored:<peer>` as
|
|
2159
|
+
`pending`, `waiting:pending`, `waiting:failed`, `done` or `failed`);
|
|
2086
2160
|
whether the shared plugin and the global CLI were installed; and `next`, the
|
|
2087
2161
|
commands that apply now, read from every source the operation has not stopped
|
|
2088
2162
|
yet (every error of `resume` ends with the same list). `resume` is left out
|
|
@@ -2092,7 +2166,11 @@ message text. `resume` does not
|
|
|
2092
2166
|
start a second runner while one is alive. Every `next` entry and error names the
|
|
2093
2167
|
operation's own coordinator, `bun <preserved source>/src/cli/main.js recovery
|
|
2094
2168
|
...`: in the middle of an upgrade the global `ahub` may still be the older
|
|
2095
|
-
release, whose `recovery` lacks these commands.
|
|
2169
|
+
release, whose `recovery` lacks these commands. The published 0.12.30 CLI also
|
|
2170
|
+
mislabels tagged waiting receipts as done and can hide the fresh-session choice,
|
|
2171
|
+
even when its status command exists. Use the printed preserved-source
|
|
2172
|
+
coordinator for status, resume and disposition; do not decide from that older
|
|
2173
|
+
CLI's receipt display. Copy that command line. When
|
|
2096
2174
|
an older coordinator started the operation, `dispose` is named from the running
|
|
2097
2175
|
release, which has it. What
|
|
2098
2176
|
each receipt allows, given what is live, is tabulated in the recovery spec
|
|
@@ -2130,6 +2208,11 @@ next actions").
|
|
|
2130
2208
|
use its offered `ahub recovery resume <id>`. Resume rechecks the source and
|
|
2131
2209
|
reconciles a commit that may already have been requested. A busy read while
|
|
2132
2210
|
that committed source is stopping stays inside the existing shutdown wait.
|
|
2211
|
+
A resumed prepared receipt with `commitSent` also polls an unavailable source
|
|
2212
|
+
within the 30-second shutdown bound, including initial database contention,
|
|
2213
|
+
without sending another commit, re-preparing or closing terminals again. Only
|
|
2214
|
+
confirmed `stopped` permits target startup; a replacement instance refuses, and
|
|
2215
|
+
expiry retains the prepared receipt and the same operation for another resume.
|
|
2133
2216
|
A stop-and-archive that meets contention instead says to retry that
|
|
2134
2217
|
disposition; resume remains refused while abandonment is partway. Successful
|
|
2135
2218
|
abort, fresh-session choice and disposal clear the earlier failure annotation.
|
|
@@ -2459,6 +2542,22 @@ the capability is absent. It never rewrites these settings. Explicit
|
|
|
2459
2542
|
refused before any local startup. Re-enable MLX or explicitly migrate the
|
|
2460
2543
|
recorded launch before recovery.
|
|
2461
2544
|
|
|
2545
|
+
## Task stalls and cancellation
|
|
2546
|
+
|
|
2547
|
+
A ready task with an ineligible reservation, no eligible peer or a cancelled dependency shows an ids-only stall cause in status and the Tasks panel. The hub reports a cause once, repeating only when the cause changes or the task is re-planned. It directs ownerless advice to the designated planner's next bounded preface and the configured supervision stream, otherwise the person's attention list; it does not create an extra ordinary turn beside backlog batching. Configure the missing capability, assign another eligible peer, re-plan or cancel the task as appropriate; a reservation never bypasses routing guards.
|
|
2548
|
+
|
|
2549
|
+
An offer to a pull-only peer adds an advisory "open <peer>: task #N is waiting for it" attention item. It clears when that exact offer is accepted, declined, superseded or genuinely delivered and settled to the addressed peer. Another inbox read, an accepted-only receipt or a person's queue completion does not prove it was read. The attention item survives peer detach and daemon restart using the saved offer's pull-only flag; it does not alter delivery state.
|
|
2550
|
+
|
|
2551
|
+
The person can retain superseded work as closed history:
|
|
2552
|
+
|
|
2553
|
+
```sh
|
|
2554
|
+
ahub task cancel <id> --reason <text> [--superseded-by <ref>] [--revision N]
|
|
2555
|
+
```
|
|
2556
|
+
|
|
2557
|
+
The console also offers cancellation with the selected task's flow revision. Approved tasks cannot be cancelled. The planner's `hub_task_cancel` tool is limited to its own unaccepted backlog/proposed work; previously accepted work requires the person. Cancellation sends the former owner/reviewer a stop notice, releases overlap/reservation participation and keeps dependents blocked with a cancelled-dependency notice. It does not stop a native turn, delete a worktree or write an outcome memory note. Cancelled work is closed history, counted separately from approved work; it does not satisfy an approval dependency. A still-running private turn keeps its privacy fence after cancellation. Use the displayed revision to avoid acting on a task that changed while it was selected.
|
|
2558
|
+
|
|
2559
|
+
The daemon advertises `task_cancel`; a current CLI refuses cancellation against older daemons. Recovery retains verified target features beside its immutable root/digest, reuses them on resume and checks only sources not yet past commit; a legacy receipt without that evidence needs a target probe only before commit. Upgrade/restart refuses a target without this feature while cancelled rows exist and names their ids. No cancelled row is rewritten as approved. An old binary launched by hand remains unsupported: it can count cancelled work as open or fail to move it. Use a compatible coordinator instead. Live task cancellation and sweep enablement are separate post-release operations.
|
|
2560
|
+
|
|
2462
2561
|
## Task idle sweep
|
|
2463
2562
|
|
|
2464
2563
|
The between-turn task sweep (#186) is disabled by default. Set `task_sweep` in
|
|
@@ -2472,6 +2571,7 @@ The between-turn task sweep (#186) is disabled by default. Set `task_sweep` in
|
|
|
2472
2571
|
"unaccepted_min": 60,
|
|
2473
2572
|
"idle_min": 120,
|
|
2474
2573
|
"review_min": 120,
|
|
2574
|
+
"ready_min": 60,
|
|
2475
2575
|
"ladder_min": 30,
|
|
2476
2576
|
"auto_reassign": false
|
|
2477
2577
|
}
|
|
@@ -2483,6 +2583,8 @@ at least 1; timeouts are bounded to the platform timer limit. Each threshold
|
|
|
2483
2583
|
measures time since the last real task history event. A ladder record does not
|
|
2484
2584
|
refresh that activity; a new event resets the ladder even at the same timestamp.
|
|
2485
2585
|
|
|
2586
|
+
Ready proposed tasks without an owner use `ready_min` and the `ready-unassigned` ladder; unresolved or cancelled dependencies do not become ready. A person's unassignment suppresses this automatic ladder until a later explicit assignment or reservation. Planner-pulled work keeps its reserved peer and current WIP/hold admission; an unavailable or full reservation never selects another worker.
|
|
2587
|
+
|
|
2486
2588
|
The first overdue sweep sends the assigned owner or reviewer one normal task
|
|
2487
2589
|
reminder. After `ladder_min`, the next sweep notifies the console and available
|
|
2488
2590
|
planner-role peers. After another interval it reports a reassignment suggestion
|
|
@@ -2564,13 +2666,15 @@ registry directories and a scrubbed environment. The normal 20-second test timeo
|
|
|
2564
2666
|
both legs. Successful fixtures are removed; a failed pair prints its preserved
|
|
2565
2667
|
fixture location with test and leak evidence for inspection.
|
|
2566
2668
|
|
|
2567
|
-
|
|
2568
|
-
|
|
2669
|
+
CI runs the pairs as four Linux shards (`bun scripts/seeded-check.ts --shard i/4`,
|
|
2670
|
+
every fourth pair, still sequential within a shard) beside the ordinary checks; the
|
|
2671
|
+
required job `seeded guards` passes only when all four shards passed (#457). The pairs
|
|
2672
|
+
do not repeat on macOS or run recursively inside `bun test`. The runner reports every
|
|
2569
2673
|
pair's elapsed seconds and the total runtime. A green ordinary check alone does
|
|
2570
2674
|
not prove these pairs.
|
|
2571
2675
|
|
|
2572
|
-
The full CI gate tests the PR head tree on Linux and macOS,
|
|
2573
|
-
|
|
2676
|
+
The full CI gate tests the PR head tree on Linux and macOS, with the seeded-guard
|
|
2677
|
+
shards running at the same time. Main and release jobs reuse only a successful full
|
|
2574
2678
|
PR or push check with the identical Git tree and all three successful jobs. An absent or
|
|
2575
2679
|
unreadable result runs the main gate again and refuses release. A manual
|
|
2576
2680
|
`prepare_bundle` dispatch builds reviewable plugin assets without publishing;
|
|
@@ -2847,6 +2951,9 @@ Qwen controlled recovery and automatic crash resume load the recorded conversati
|
|
|
2847
2951
|
|
|
2848
2952
|
Use ahub roster add jcode, then ahub jcode --mode headless [--model <alias>] [--provider-profile <name>]. The person launcher configures only agent-hub-jcode in .jcode/mcp.json; run ahub init afterwards to ignore the untracked machine-path file. Conductor/dashboard starts read that entry without editing it. Preview starts nothing, and ahub stop jcode stops only the owned private daemon/ACP groups. jcode_cmd, jcode_home and jcode_provider_profile are machine-local and never editable from settings.
|
|
2849
2953
|
|
|
2954
|
+
After upgrading to the recipient-retry release, a Jcode project MCP entry written before `AGENTHUB_DELIVERY_ONLY` was added is intentionally stale. Once per project, the person runs `ahub jcode --mode headless` before using conductor/dashboard starts. The launcher rewrites only the owned entry with the delivery-only marker, preserving foreign entries and refusing collisions; recovery relaunches already use this CLI path. Readiness checks never rewrite the file, and an explicit false marker or any other drift remains refused. Until that rewrite, daemon starts keep their actionable stale-entry refusal rather than advertising a retry tool Jcode cannot use.
|
|
2955
|
+
|
|
2956
|
+
|
|
2850
2957
|
Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or runtime mode mapping is invented. Quota and consumption remain unknown. Version 0.94.0 cannot prove native session/load identity, so attached Jcode blocks controlled recovery before effects and crash recovery asks for deliberate native reopening. A requested load without an echoed identity refuses; no fresh session is presented as restored. Provider/tool/native teardown receipts remain unverified in the pinned contract report.
|
|
2851
2958
|
|
|
2852
2959
|
# Headless ACP watch (#286)
|
|
@@ -2975,7 +3082,7 @@ Create a phase with `ahub release new <name> <goal> <order>`, inspect `list` or
|
|
|
2975
3082
|
`show`, and set planned start/cut/ship with `plan <name> <revision> <dates-json>`.
|
|
2976
3083
|
`activate`, `freeze`, `ship` and `drop` need its current revision. Only a person
|
|
2977
3084
|
freezes, ships, drops or edits frozen scope. Ship records the first ship time
|
|
2978
|
-
only after every member is approved or moved out; it runs no tag or publish.
|
|
3085
|
+
only after every member is approved, cancelled or moved out; it runs no tag or publish.
|
|
2979
3086
|
The dashboard shows phase progress, blocking dependencies, dates and remaining
|
|
2980
3087
|
work. Actual task dates come from execution/review/approval history, never input.
|
|
2981
3088
|
|