@staix/agent-hub 0.12.20 → 0.12.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +6 -5
- package/docs/agent-notes/adapters.md +9 -2
- package/docs/agent-notes/bus.md +5 -2
- package/docs/agent-notes/daemon.md +8 -2
- package/docs/agent-notes/local-worker.md +3 -1
- package/docs/agent-notes/tasks.md +3 -1
- package/docs/agent-notes/tests.md +3 -2
- package/docs/bench.md +143 -0
- package/docs/events.md +2 -1
- package/docs/operations.md +271 -46
- package/docs/quickstart.md +12 -10
- package/docs/research.md +92 -0
- package/docs/security.md +45 -10
- package/docs/smoke.md +79 -0
- package/docs/specs/2026-09-19-agent-hub-design.md +194 -20
- package/docs/specs/2026-09-20-upgrade-recovery-design.md +68 -10
- package/docs/verified.json +28 -17
- package/package.json +1 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +3 -2
- package/src/adapters/acp.ts +67 -6
- package/src/adapters/codex-appserver.ts +67 -2
- package/src/adapters/local-worker.ts +4 -3
- package/src/adapters/pi.ts +58 -4
- package/src/cli/bench.ts +287 -0
- package/src/cli/console-state.ts +226 -28
- package/src/cli/console.ts +16 -4
- package/src/cli/facts-hook.ts +50 -8
- package/src/cli/help.ts +10 -0
- package/src/cli/identity.ts +10 -4
- package/src/cli/launch.ts +96 -17
- package/src/cli/main.ts +159 -18
- package/src/cli/preview.ts +13 -3
- package/src/cli/status-lines.ts +2 -1
- package/src/cli/terminal-recovery.ts +83 -31
- package/src/cli/upgrade-runtime.ts +67 -18
- package/src/cli/upgrade.ts +81 -9
- package/src/hub/bench.ts +211 -0
- package/src/hub/bus.ts +19 -4
- package/src/hub/conductor.ts +22 -21
- package/src/hub/config-trust.ts +1 -0
- package/src/hub/control-client.ts +4 -1
- package/src/hub/daemon.ts +346 -40
- package/src/hub/delivery-journal.ts +6 -6
- package/src/hub/events.ts +2 -1
- package/src/hub/lifecycle.ts +8 -13
- package/src/hub/manager.ts +16 -14
- package/src/hub/permission-mode.ts +44 -0
- package/src/hub/recovery-store.ts +21 -9
- package/src/hub/registry.ts +36 -22
- package/src/hub/research.ts +255 -0
- package/src/hub/tasks.ts +70 -43
- package/src/hub/tool-refusal.ts +7 -0
- package/src/hub/ui.ts +4 -1
- package/src/local/tools.ts +14 -10
- package/src/pi/process-signature.ts +23 -0
- package/src/pi/tool-receipts.ts +7 -1
- package/src/ui/index.html +83 -6
- package/src/ui/task-progress.ts +33 -0
|
@@ -89,7 +89,8 @@ Facts below are tagged **verified** (measured on 2026-09-19 on the owner's Mac)
|
|
|
89
89
|
7. Quota relay hands open tasks to the `local` peer first, then waits for the window
|
|
90
90
|
reset for judgment-heavy classes. Task-level escalation on verification failure.
|
|
91
91
|
8. Safety defaults: cross-peer text is framed as untrusted; permission prompts stay on
|
|
92
|
-
unless `--unattended
|
|
92
|
+
unless `--unattended` or an operator-selected permission mode (issues #240,
|
|
93
|
+
#242); ports bind loopback only; Kimi ACP permission requests are
|
|
93
94
|
relayed to the hub console. Loopback is not enough on its own (any web page can open a
|
|
94
95
|
WebSocket to 127.0.0.1), so the control WS requires a per-run token and both hub
|
|
95
96
|
servers refuse requests that carry an `Origin` header (amended in M1).
|
|
@@ -97,8 +98,9 @@ Facts below are tagged **verified** (measured on 2026-09-19 on the owner's Mac)
|
|
|
97
98
|
10. Shared memory reuses claude-mem as the single store; the hub never runs its own
|
|
98
99
|
memory database. Native capture stays where it exists (Claude hooks, Codex plugin,
|
|
99
100
|
Kimi transcript bridge); the hub captures only the local worker and adds
|
|
100
|
-
cross-platform recall, task-scoped briefs and explicit shared notes.
|
|
101
|
-
|
|
101
|
+
cross-platform recall, task-scoped briefs and explicit shared notes. Hub tool calls
|
|
102
|
+
are not captured; Tasks alone decides what screened tool text reaches memory.
|
|
103
|
+
The bus still passes messages, never transcripts.
|
|
102
104
|
|
|
103
105
|
## Design
|
|
104
106
|
|
|
@@ -279,9 +281,10 @@ peer. Peer ids claimed over the control WS must not be `user` or a hub-managed a
|
|
|
279
281
|
injection is dropped for the same reason as `dynamicTools`.
|
|
280
282
|
- PII (amended in M4): a task matching `signals.pii_patterns` is owned by `local` or by
|
|
281
283
|
nobody; its envelopes are `private` (console tail and `hub.log` print a stub), lists show
|
|
282
|
-
`[pii]` to everyone but `local
|
|
283
|
-
reviewer is the console user; `local` answers such a turn
|
|
284
|
-
of its history, refuses it when the only gateway
|
|
284
|
+
`[pii]` to everyone but `local` inside a PII turn; `ahub task show` is the one place
|
|
285
|
+
the console reads it. The reviewer is the console user; `local` answers such a turn
|
|
286
|
+
to the console only, keeps it out of its history, refuses it when the only gateway
|
|
287
|
+
is off campus (Cloudflare Access), and
|
|
285
288
|
nothing reaches claude-mem (no brief, no note, no capture), because claude-mem's observer is
|
|
286
289
|
a cloud model (verified: `/api/health` reports `ai.provider: claude`).
|
|
287
290
|
|
|
@@ -486,7 +489,8 @@ inside a peer.
|
|
|
486
489
|
### Safety
|
|
487
490
|
|
|
488
491
|
- Untrusted framing on all cross-peer text; standing instruction once per session.
|
|
489
|
-
- `ahub claude` and `ahub codex` keep
|
|
492
|
+
- `ahub claude` and `ahub codex` keep native permission defaults unless the person
|
|
493
|
+
selects a permission mode (issues #240, #242). `--unattended` opts into
|
|
490
494
|
`--dangerously-skip-permissions` (Claude) and `--dangerously-bypass-approvals-and-sandbox`
|
|
491
495
|
(Codex 0.154.0 documents this flag, not `--yolo`) and prints a warning.
|
|
492
496
|
- Kimi and local tools: cwd-scoped, secrets denylist (a secrets directory, `.env*`, keys).
|
|
@@ -496,7 +500,7 @@ inside a peer.
|
|
|
496
500
|
### Configuration and state
|
|
497
501
|
|
|
498
502
|
- `.agenthub/config.json` (roles, ports, filter tiers, watchdog), `.agenthub/routing.toml`.
|
|
499
|
-
- `.agenthub/state/` gitignored: `
|
|
503
|
+
- `.agenthub/state/` gitignored: `status.json` (with the daemon's pid and process signature, #226; daemons up to 0.12.20 also wrote `hub.pid`), `control-token` (0600, per run),
|
|
500
504
|
`hub.db` (tasks, messages, budget; from M4), `hub.log`, `switchyard.toml`, `checkpoint.md`.
|
|
501
505
|
- Env: `AGENTHUB_STATE_DIR`, `AGENTHUB_OMNIROUTE_URL`, `OMNIROUTE_API_KEY`,
|
|
502
506
|
`AGENTHUB_SWITCHYARD_BIN`, `AGENTHUB_UNATTENDED`.
|
|
@@ -763,7 +767,8 @@ session modes (`default`, `plan`, `auto`, `yolo`) but nothing per server or tool
|
|
|
763
767
|
`hub_send` or a task tool, are answered with their `allow_once` option by the
|
|
764
768
|
hub, without a console prompt, and logged by tool name only. This matches the
|
|
765
769
|
`approval_mode = "approve"` Codex already gets for the same tools. Every other
|
|
766
|
-
request keeps the console path
|
|
770
|
+
request keeps the console path unless the person opts into the permission modes
|
|
771
|
+
below (issues #240, #242); `allow_always` is never chosen automatically.
|
|
767
772
|
- For the other tools, the console payload falls back to the streamed argument
|
|
768
773
|
text once it is a complete JSON object. A partial stream stays unresolved and
|
|
769
774
|
keeps `allow_always` withheld.
|
|
@@ -776,6 +781,68 @@ session modes (`default`, `plan`, `auto`, `yolo`) but nothing per server or tool
|
|
|
776
781
|
configured server of the same name, so only the hub's `agent-hub` server can
|
|
777
782
|
produce the approved names.
|
|
778
783
|
|
|
784
|
+
## Amendment: operator permission modes (issues #240, #242)
|
|
785
|
+
|
|
786
|
+
- Modes: ask leaves native decisions unchanged; ask-when-needed uses native
|
|
787
|
+
Kimi/Codex policies or scoped Claude/Pi/local grants; never-ask suppresses
|
|
788
|
+
prompts within each peer's existing execution boundaries.
|
|
789
|
+
- Runtime CLI permission changes are refused from ordinary agent shells.
|
|
790
|
+
Never-ask needs --yes; console mode selection needs a separate y. These
|
|
791
|
+
policy/role checks do not contain a hostile same-user shell: Kimi can clear
|
|
792
|
+
markers, use --yes or read the control token and impersonate the console.
|
|
793
|
+
The security and operations guides name that boundary explicitly.
|
|
794
|
+
- permission_modes defaults merge per peer across config files. Automatic
|
|
795
|
+
effects stop at ask-when-needed. Never-ask from an applied untracked config remains ask until
|
|
796
|
+
a person's source-labelled console y at hub start; no boot --yes applies it.
|
|
797
|
+
Git-tracked mode defaults are ignored and never offered for confirmation.
|
|
798
|
+
Every non-ask start logs mode and source (config file or runtime choice). Successful
|
|
799
|
+
runtime changes clear pending config confirmations; startup choices are reconciled
|
|
800
|
+
under the peer fence before a new adapter is exposed to bus delivery. Runtime changes and
|
|
801
|
+
confirmations remain daemon-local and expire on stop.
|
|
802
|
+
- Newly added native peers replay their non-offline state to drain queued work,
|
|
803
|
+
publish state telemetry and persist sessions. Offline/absent ask clears only
|
|
804
|
+
the hub choice. Unattended metadata is saved after successful startup, and
|
|
805
|
+
concurrent joined starts with different flags are refused. Refused default
|
|
806
|
+
confirmation remains handled until state changes; Esc defers without declining.
|
|
807
|
+
- Kimi mapping requires the actual Kimi Code CLI identity: yolo for
|
|
808
|
+
ask-when-needed, auto for never-ask, default for ask. Another ACP agent starts fresh or resumed as unmanaged: its reported mode is
|
|
809
|
+
untouched, and runtime changes are refused until its table exists. Set-mode replies precede prompts;
|
|
810
|
+
missing ids/refused startup changes fail. A timeout is unknown/offline and
|
|
811
|
+
the owned process group stops, so a late reply cannot restore a live peer.
|
|
812
|
+
Loaded non-default Kimi modes are reset for project ask.
|
|
813
|
+
- Codex overlays on-request/never on every outgoing turn/start without changing
|
|
814
|
+
sandbox fields. Ask restores a known native policy once after an accepted
|
|
815
|
+
turn; rejected restoration remains pending. Unknown native baseline refuses
|
|
816
|
+
restoration. Actual native unattended flags, not broker-wide flags, govern
|
|
817
|
+
the refusal to change a bypassed session.
|
|
818
|
+
- Claude ask-when-needed allows only Read/Edit/Write/MultiEdit/NotebookEdit/LS
|
|
819
|
+
and bounded Glob/Grep targets resolved with realPath beneath project root,
|
|
820
|
+
outside .agenthub/.git/.claude/.codex/.qwen/.kimi/.pi/.mcp.json. Missing/nonresolving or escaping targets,
|
|
821
|
+
protected case aliases, symlinks and uncertain wildcard/filter targets yield
|
|
822
|
+
no decision. Never-ask answers allow; ask and transport errors decide nothing.
|
|
823
|
+
Merged/generated settings are 0600 state files passed by path, never inline
|
|
824
|
+
in argv. Preview writes no settings file. The owning launcher removes its settings file
|
|
825
|
+
after native exit; earlier active or unknown launchers retain theirs. Verified
|
|
826
|
+
dead wrapper and native identities permit crash fallback cleanup. Without
|
|
827
|
+
separate native identity proof, prior files remain for manual inspection.
|
|
828
|
+
- Permission-only Claude PreToolUse never drives busy state. Only the former
|
|
829
|
+
observation purposes retain native turn bookkeeping. Hook identity/purpose
|
|
830
|
+
are launch/session bound; unverified hook status reads unverified.
|
|
831
|
+
- Pi/local read never asks. Ask-when-needed grants write/edit inside the project, outside the shared native
|
|
832
|
+
configuration segments (.claude/.codex/.qwen/.kimi/.pi/.mcp.json, compared folded and by the path within the
|
|
833
|
+
project) and never through a hard link; bash and mutating
|
|
834
|
+
git retain console approval. Never-ask grants once, retaining sandbox and
|
|
835
|
+
path guards; no mode gives allow-always. ACP tools have no hub sandbox and
|
|
836
|
+
the never-ask confirmation names that difference.
|
|
837
|
+
- Console-role permission and permission_default requests are additive;
|
|
838
|
+
ordinary tools/conductor/messages cannot change or confirm modes. Status
|
|
839
|
+
includes non-ask/unverified/unknown mode state and pending defaults; facts
|
|
840
|
+
replies include permission and authenticated projectRoot. Unknown requests
|
|
841
|
+
are answered, so PROTOCOL remains unchanged. permission_mode events retain
|
|
842
|
+
schema 1 and include only peer/from/to, never tool arguments.
|
|
843
|
+
- Live benign Kimi/Claude results and unverified Codex/Pi limits are recorded
|
|
844
|
+
in docs/smoke.md. No extra account prompts accompany these review corrections.
|
|
845
|
+
|
|
779
846
|
## Amendment: approval notifications and timeout (issue #5)
|
|
780
847
|
|
|
781
848
|
- A waiting permission request raises one macOS notification (`osascript`) with
|
|
@@ -994,7 +1061,11 @@ session modes (`default`, `plan`, `auto`, `yolo`) but nothing per server or tool
|
|
|
994
1061
|
awaited an approval. An approval is saved before its dependents are assigned,
|
|
995
1062
|
so the daemon's 60 s release timer sweeps for ownerless tasks whose last event
|
|
996
1063
|
is `blocked` or `ready` and that wait for nothing: each is offered once per hub
|
|
997
|
-
run, once an attached peer can take it, outside recovery operations.
|
|
1064
|
+
run, once an attached peer can take it, outside recovery operations. An offer
|
|
1065
|
+
is used up only by an assignment, after an approval and on the timer alike;
|
|
1066
|
+
failed dependent reads, ready writes or assignments do not escape a saved
|
|
1067
|
+
approval. Their notices are best effort because notification can read the
|
|
1068
|
+
same unavailable board. An ownerless task stays eligible once a peer can take it.
|
|
998
1069
|
- A recovery commit also waits for task operations in flight and for completion
|
|
999
1070
|
checks queued or running: both can write the board after its integrity digest
|
|
1000
1071
|
(a check the commit's stop kills records `check interrupted`).
|
|
@@ -1360,14 +1431,59 @@ approval. Deny is direct. Pending requests include expiry and are withdrawn by
|
|
|
1360
1431
|
Panels expose Peers, Approvals, Tasks, Queue and Events with bounded polling and
|
|
1361
1432
|
Unicode cell widths, fall back below 80x24, and restore terminal state on exit.
|
|
1362
1433
|
|
|
1434
|
+
Whole-board progress (#246) uses one pure `taskProgress` function shared by the
|
|
1435
|
+
console and hashed dashboard script. It reads only public id/state/deps fields;
|
|
1436
|
+
PII stubs count like other tasks. Waiting partitions proposed tasks whose public
|
|
1437
|
+
dependencies are not approved, including unknown dependencies. Approved/all gives
|
|
1438
|
+
the done fraction (zero on an empty board). Four stages are proposed, in progress,
|
|
1439
|
+
in review and approved; changes requested returns to stage two and is marked.
|
|
1440
|
+
The console Tasks panel has a 20-cell ASCII summary bar and fixed four-cell row
|
|
1441
|
+
meters, preserving width and color-off geometry. Cells and percentage round down;
|
|
1442
|
+
count labels use importance order changes requested, review, waiting, in progress,
|
|
1443
|
+
proposed, then unknown when nonzero, and drop only from the end. The stream count is in the fixed footer,
|
|
1444
|
+
from existing all-state status counts; it makes no board fetch and retains a
|
|
1445
|
+
row-one scroll region for terminal scrollback. Loading/failed reads never imply
|
|
1446
|
+
confirmed empty progress. Dashboard filters affect rows only, not totals. Its
|
|
1447
|
+
full-width stacked SVG and stages have text equivalents; the existing signature
|
|
1448
|
+
guard prevents unchanged snapshots from mutating the progress live region.
|
|
1449
|
+
System/Light/Dark choice is applied as `data-theme` before first paint, persists
|
|
1450
|
+
in a one-year host-scoped `SameSite=Strict` cookie through guarded access and
|
|
1451
|
+
follows OS CSS preference on System. Cookie port independence shares the choice
|
|
1452
|
+
between hub starts and projects. The shared model is injected before the page's
|
|
1453
|
+
own inline script/style CSP hashes, with no new control message or CLI JSON change.
|
|
1454
|
+
UI public rows expose optional public-view deps for waiting. This is additive
|
|
1455
|
+
metadata enrichment of the existing ui_snapshot payload, not a changed control
|
|
1456
|
+
message envelope/operation, so it does not bump PROTOCOL. Unknown task states
|
|
1457
|
+
count in an explicit unknown bucket with stage zero; no NaN or prototype-key
|
|
1458
|
+
updates are permitted. Approval fraction is derived from counts/total at display
|
|
1459
|
+
time, avoiding a redundant floating-ratio field.
|
|
1460
|
+
|
|
1363
1461
|
Console semantic colors (issue #201) use spans with a fixed terminal-native
|
|
1364
1462
|
palette: cyan information, bold cyan active/selected labels, green availability
|
|
1365
1463
|
and success, yellow attention/waiting, red failure/intervention, and restrained
|
|
1366
1464
|
bright-black metadata. Offline peers, ordinary titles, action details and body
|
|
1367
1465
|
lines use the default foreground. Existing labels, selection markers and
|
|
1368
|
-
confirmation prompts remain sufficient without color.
|
|
1369
|
-
|
|
1370
|
-
|
|
1466
|
+
confirmation prompts remain sufficient without color. Console stream headers
|
|
1467
|
+
color meaningful tokens only (#239; dated issue Decisions): Claude bright blue
|
|
1468
|
+
(94), Codex bright cyan (96), all other peers default; `task` magenta (35, never
|
|
1469
|
+
bold), numbers bold default foreground (1), task references magenta underlined
|
|
1470
|
+
(4;35), and other issue references underlined default foreground (4). No token
|
|
1471
|
+
SGR equals a state or peer SGR. Green/yellow/red remain states/approvals/failures,
|
|
1472
|
+
cyan remains navigation. Case-insensitive `task #N`, `Task #N`, `[task #N]` and
|
|
1473
|
+
`[review #N]` identify task references; unbracketed prose `review #N` remains an
|
|
1474
|
+
issue reference. Ordinary words keep default foreground;
|
|
1475
|
+
there is no hashing or user theme.
|
|
1476
|
+
Only hub-written peer slots, state words and structural markers receive their
|
|
1477
|
+
semantic tones; title words and markers cannot choose them. Numeric tokens have
|
|
1478
|
+
whole-token boundaries, so UUIDs and ISO identifiers stay plain. Legacy notices
|
|
1479
|
+
lack typed reference ranges: the task/review prefix heuristic is bounded by a
|
|
1480
|
+
`ponytail:` comment; other `#N` tokens use the issue tone until structured notice
|
|
1481
|
+
spans classify assign/which references. Header text crosses `terminalText` before tokenization. Wrapped headers normalize
|
|
1482
|
+
tabs to spaces first; plain headers retain their original tabs in both color modes. Wrapped spans retain the source classification. After a projection
|
|
1483
|
+
miss on the first physical header, only structural tones remain. A missed
|
|
1484
|
+
continuation and all later continuations are fully plain. Projection advances
|
|
1485
|
+
a span index through the source once, keeping long permission titles bounded. Bodies and every
|
|
1486
|
+
command-output line stay plain. Denial requests and observed expiry/cancellation
|
|
1371
1487
|
are red; an answered remote closure lacks option-kind metadata and is not
|
|
1372
1488
|
guessed to be a denial.
|
|
1373
1489
|
|
|
@@ -1654,7 +1770,10 @@ push `accepted` and show none of them.
|
|
|
1654
1770
|
to the newest end of the cache) for `reply_to` like a push, and a read clears
|
|
1655
1771
|
the peer's failure streak as a completed push does. If that journal write fails, only this peer's queue
|
|
1656
1772
|
and preface are put back (every pause stays) and the bus stops with
|
|
1657
|
-
`delivery journal unavailable`. A
|
|
1773
|
+
`delivery journal unavailable`. A refused or failed `resolveDelivery` likewise
|
|
1774
|
+
puts back only that peer's queue and preface and keeps every pause. Queue
|
|
1775
|
+
contents change in place, preserving arrays held by a suspended drain; only
|
|
1776
|
+
the constructor and recovery restore reload a bus snapshot. A pull is not a native turn and is not
|
|
1658
1777
|
counted as supervision. The row is completed at hand-out, before anything
|
|
1659
1778
|
shows the model saw it: a reply lost on the way, a tool call cancelled with
|
|
1660
1779
|
Esc or a plugin that dies loses the batch (a `ponytail:` ceiling in
|
|
@@ -1789,9 +1908,9 @@ acts on the stopped state directory.
|
|
|
1789
1908
|
Checked, then renamed by path: a symlink swapped in between still wins
|
|
1790
1909
|
(marked `ponytail:`; `renameat` on a held descriptor would close it).
|
|
1791
1910
|
- Between stop and act: after `stopProject` the CLI takes the project's
|
|
1792
|
-
registry claim (`Registry.claim` with its own pid), the claim a daemon must
|
|
1911
|
+
registry claim (`Registry.claim` with its own pid and process signature), the claim a daemon must
|
|
1793
1912
|
hold to run, and checks that no manifest names a daemon whose pid is alive
|
|
1794
|
-
or uncertain (`
|
|
1913
|
+
or uncertain (`processLiveness`, the rule `inspectProject` uses, #226); either failing
|
|
1795
1914
|
means a hub started in between and nothing is reset. A reset's claim carries
|
|
1796
1915
|
the instance prefix `reset-`, so losing the claim to a concurrent reset says
|
|
1797
1916
|
so. A crashed daemon's manifest (`status.json`, `control-token`, `hub.pid`
|
|
@@ -1800,7 +1919,7 @@ acts on the stopped state directory.
|
|
|
1800
1919
|
removes it and `--all` archives it. With the claim held, the CLI checks the
|
|
1801
1920
|
machine's recovery lock again, so an upgrade or recovery that took it in
|
|
1802
1921
|
between does not run beside the reset. The claim is released when the reset
|
|
1803
|
-
ends; a reset that dies leaves a dead pid, which the next claim takes over.
|
|
1922
|
+
ends; a reset that dies leaves a dead or reused pid with its signature, which the next claim takes over.
|
|
1804
1923
|
- Failures: the plan is read only for the dry run, so `--all --yes` archives a
|
|
1805
1924
|
state directory it cannot read as it is (its dry run says what it could not
|
|
1806
1925
|
read). A failure after the stop says how far it got. A runtime reset that
|
|
@@ -1849,9 +1968,8 @@ acts on the stopped state directory.
|
|
|
1849
1968
|
text right after the pattern check and before triage. "Held as private" is met
|
|
1850
1969
|
by holding the task back entirely: until the verdict it is not on the board, so
|
|
1851
1970
|
no envelope, notice, triage call, brief or note of the hub's can read it. The
|
|
1852
|
-
local worker
|
|
1853
|
-
|
|
1854
|
-
gap for every hub tool, not closed here). Writing it as
|
|
1971
|
+
local worker never captures hub tool calls (#230), so a proposal's arguments
|
|
1972
|
+
cannot bypass the verdict through capture. Writing it as
|
|
1855
1973
|
a PII task first was rejected: a PII task opening lifts every silent turn-free
|
|
1856
1974
|
cohort for good and switches facts off (#107, #108), so every proposal would do
|
|
1857
1975
|
that. The proposal's tool call waits for the verdict, as it already waits for
|
|
@@ -1930,3 +2048,59 @@ acts on the stopped state directory.
|
|
|
1930
2048
|
before any measurement: the model itself labels at least 90% of the positives
|
|
1931
2049
|
`pii` (an unknown verdict counts as a miss). The report goes to
|
|
1932
2050
|
`docs/verification/`; the script exits 1 under the bound.
|
|
2051
|
+
|
|
2052
|
+
## Amendment: research records (issue #247)
|
|
2053
|
+
|
|
2054
|
+
- Opt-in per project (`research.enabled`, off by default). When a task is approved, the daemon builds its record from
|
|
2055
|
+
the project's `events.jsonl` with the same function `ahub research backfill` uses (`taskRecords` in
|
|
2056
|
+
`src/hub/research.ts`), so live and backfilled records agree, and appends it to the machine-wide store
|
|
2057
|
+
`~/.agenthub/research/<sha256(project id)[0:16]>.jsonl`. Records hold ids, states, counts, tokens and times only,
|
|
2058
|
+
because the events do; schema and fields: [research](../research.md).
|
|
2059
|
+
- The board has no terminal state but `approved`, and it is final, so each approved task gets one record; a person's
|
|
2060
|
+
later verdict (`ahub task label`, including `abandoned`) is a separate label record bound to the task's proposal
|
|
2061
|
+
time. A task is keyed by project, id and proposal time, because `ahub reset --all` restarts the ids and the store
|
|
2062
|
+
keeps the older records. Measures (success, first pass, rework, check failures over checks run, tokens and wall time
|
|
2063
|
+
per task) are derived when reported, never stored.
|
|
2064
|
+
- The record counts everything attributed to the task, the turn that approved it included: that turn ends after the
|
|
2065
|
+
approval and its usage arrives later, so the writer waits until no open turn is attributed to the task (polled every
|
|
2066
|
+
10 s, at most 30 minutes; a stopping hub writes once its peers have stopped). The first record written for a
|
|
2067
|
+
task is final; a label binds to the current board's task, else to the store's only record with that id, or with
|
|
2068
|
+
`--created` to a named one from before a reset. Task events carry the board's move `reason` (a closed
|
|
2069
|
+
list) so reassignments are counted by reason.
|
|
2070
|
+
- Recording never blocks or fails the task flow: the writer runs after the board event, and a failure is one
|
|
2071
|
+
hub.log line per run. ponytail: it reads the whole events file for each record; an incremental per-task index
|
|
2072
|
+
if that file grows large.
|
|
2073
|
+
- Agents may read the measures and export; backfill and labels are a person's (identity gate).
|
|
2074
|
+
|
|
2075
|
+
## Amendment: proven Pi tool refusals and idle exit recovery (issues #254, #255)
|
|
2076
|
+
|
|
2077
|
+
- A trusted guard uses `PreEffectToolRefusal` only when that operation has performed no task or board effect; PII screening and its telemetry record may precede the refusal. Pi receives the same `error: <message>` refusal as the control client, and its session/call receipt is `done`. Initial task ownership/dependency/state checks and conductor entry peer/mode/assignment/escalation validation opt into the type; shared helpers default to ordinary errors, and conductor checks after an awaited release validation stay ordinary. Generic errors, board readback failures after a write, and receipt settlement write failures remain uncertain/pending and are never repeated. A legacy pending row has no pre-effect proof in its stored fingerprint/state/result, so startup preserves it; neither present board state nor a matching error message establishes historical refusal.
|
|
2078
|
+
- Each Pi owner reports one exit with cause, exit code or signal, whether startup completed, whether a turn/tool was active, whether teardown was expected, and the last validated tool name only. TUI shutdown/owner-loss and verified stop teardown lack observed OS status and record unknown. A successfully stopped claimed TUI owner reports once; a never-owned launch reports no invented exit. Internal teardown notices direct inspection and `ahub pi`, without claiming a person requested them. Console notices name the next action or automatic-start state; headless code 0 is still an exit and settles active deliveries as uncertain.
|
|
2079
|
+
- With `pi.auto_start`, an unexpected idle headless exit attempts its verified persisted session once in a 60 s window. The daemon owns the attempt/window across adapter replacements, blocks throughout an in-flight attempt, and rearms the 60 s window when that attempt settles. It checks current-owner identity, completed startup, turn/tool inactivity, start serialization, shutdown and recovery before and after awaited receipt drain/session capture. Missing or invalid persisted state leaves Pi offline with `ahub pi` guidance, with no fresh-session fallback. A second exit inside the window stays offline. Requested stops, stale owners, startup failures, active turns/tools and native terminal exits never trigger this automatic path; crash recovery's existing #66 behavior remains separate.
|
|
2080
|
+
## Amendment: benchmarks (issue #251)
|
|
2081
|
+
|
|
2082
|
+
- `ahub bench` runs a person's suite file (tasks with a starting commit, an optional setup and a verify command)
|
|
2083
|
+
against the peers attached to a hub, in a project opted in with `bench.enabled`, because every attempt resets the work
|
|
2084
|
+
tree (`git checkout --force --detach <commit>` with HEAD checked against the pin, `git clean -ffdx -e /.agenthub`, then a
|
|
2085
|
+
clean-tree check). Before
|
|
2086
|
+
anything changes the runner requires the project to be the root of its repository, nothing tracked under `.agenthub/`
|
|
2087
|
+
(in any letter case) in the tree or in any suite ref, every ref to be a commit, which it pins for the run, and a
|
|
2088
|
+
clean tree. The runner is a console client: it proposes each
|
|
2089
|
+
task as the console does and polls the board, so the task flow is unchanged and no new control request exists.
|
|
2090
|
+
- `setup` and `verify` run in their own process group, bounded; the group is stopped at the bound, on an interrupt and
|
|
2091
|
+
when the command exits. An approved attempt's measures come from #247's `taskRecords` for the task proposed last with
|
|
2092
|
+
that id, read once the turns started since its proposal have ended (waiting only while their peers are busy or
|
|
2093
|
+
paused, at most 10 minutes, outside the attempt's duration); a timeout, an error, an interrupted wait, a wait that
|
|
2094
|
+
runs out with the turn still open, or a hub status that cannot be read while it is open leaves none, never partial
|
|
2095
|
+
ones. The fingerprint lists only the peers attached at the start.
|
|
2096
|
+
- Results go to `~/.agenthub/bench/<run>.jsonl` (ids, outcomes, exit codes, counts, times; never suite text or command
|
|
2097
|
+
output). A run's state comes from its end record or its runner's liveness (`processLiveness`). Comparisons are
|
|
2098
|
+
derived when asked: an arm is every run of it that is over (a stopped run included), runs of different suites or
|
|
2099
|
+
suite versions are not mixed unless asked, and each difference has a seeded 95% bootstrap interval, inconclusive
|
|
2100
|
+
below five attempts counted for that measure per arm (errors are not counted for pass rate or wall time).
|
|
2101
|
+
- A task that times out stops the run, because an agent may still work in the tree the next attempt would reset.
|
|
2102
|
+
ponytail: a board state to withdraw an open task would let the run continue. The fingerprint holds what the hub's
|
|
2103
|
+
status reports (a requested model for Pi, permission modes once #242 lands); ponytail: read each peer's launch
|
|
2104
|
+
settings for the rest.
|
|
2105
|
+
- The dashboard snapshot carries run summaries and per-arm measures only. `bench run` is a person's (identity gate,
|
|
2106
|
+
wherever `--json` stands); reading results is not. Schema and commands: [bench](../bench.md).
|
|
@@ -50,6 +50,9 @@ parents/hops, retries, dedupe state, prefaces, manual pauses and peer descriptor
|
|
|
50
50
|
The existing task and budget databases remain authoritative. A mismatched or
|
|
51
51
|
corrupt snapshot blocks startup. Snapshot restoration precedes peer attachment;
|
|
52
52
|
release is idempotent and retires replayable snapshot state before delivery.
|
|
53
|
+
Journal-backed restoration retains missing empty queue entries from the committed
|
|
54
|
+
bus snapshot, including peers that remain offline. The journal stays authoritative
|
|
55
|
+
for queued work and receipts; a non-empty snapshot queue is never replayed over it.
|
|
53
56
|
Release atomically moves that snapshot to a private per-operation archive before
|
|
54
57
|
lifting the hold. Archives retain evidence for an uncertain release and are never
|
|
55
58
|
automatically replayed. Preparation freezes the peer roster; a new unplanned peer
|
|
@@ -322,7 +325,12 @@ nor accepted when the target cannot read recovery waivers; `status` then says
|
|
|
322
325
|
why in its own `freshSession` field, since `next` holds commands only. A runner
|
|
323
326
|
record that cannot be read shows as `unknown` in `status`, never as no runner;
|
|
324
327
|
while it reads so, resume, abort and dispose are all refused (the runner claim
|
|
325
|
-
cannot tell its owner), so `next` names only `status` again.
|
|
328
|
+
cannot tell its owner), so `next` names only `status` again. The runner row
|
|
329
|
+
carries its runner's process signature (#226): a row whose pid now belongs to
|
|
330
|
+
another process (after a reboot, for example) is no runner and the next claim
|
|
331
|
+
replaces it; one whose process exists but cannot be identified is `unknown`, and
|
|
332
|
+
the claim refuses it with that reason, never a raw `kill` error. A row an older
|
|
333
|
+
runner wrote has no signature and is judged by its pid alone, as before. Otherwise `status` and every error that lists choices build them with one function
|
|
326
334
|
(`nextActions`), in this order: resume (which also launches a failed peer
|
|
327
335
|
again), unless it can never get past what is live (`resumeBlocked`): a
|
|
328
336
|
recorded final refusal (staging refused the fixed target or preserved source), a
|
|
@@ -330,11 +338,11 @@ missing project directory, a hub that speaks another control protocol, a
|
|
|
330
338
|
runtime other than the one the receipt expects (a replaced source; a target not
|
|
331
339
|
fenced to this operation, another instance or another version), a stopped
|
|
332
340
|
pending source, a prepared source of a #215 coordinator that stopped with no
|
|
333
|
-
commit request, a target that stopped after it started
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
341
|
+
commit request, a target that stopped after it started when the operation's
|
|
342
|
+
coordinator predates #225, or any other stopped runtime without this operation's
|
|
343
|
+
unreleased restart snapshot to start from (unavailable, starting or stopping is
|
|
344
|
+
waited for). A target that stopped after it started, with that snapshot, is
|
|
345
|
+
started again by resume (#225, below). Then abort where `abortRefusal` allows it; a fresh session for each failed
|
|
338
346
|
Codex or Claude restoration, only where resume is offered (resume launches the
|
|
339
347
|
new session, and dispose refuses `--fresh-session` on the same predicate); and
|
|
340
348
|
last stop-and-archive where `disposeRefusal` allows it, or else `wait until
|
|
@@ -366,7 +374,15 @@ target instance. It is live when its process signature matches, gone when the
|
|
|
366
374
|
pid no longer exists (ESRCH) or now belongs to another process, and unknown when
|
|
367
375
|
the pid exists but its identity cannot be read. Unknown is never treated as gone. At planning, an
|
|
368
376
|
unknown Claude launcher blocks: whether the attached session is managed cannot
|
|
369
|
-
be told.
|
|
377
|
+
be told. A row that fails validation is never dropped and never read as "no
|
|
378
|
+
launcher" (#228): unless its readable `peer`, `projectRoot` or `instanceId` names
|
|
379
|
+
another launcher, it is unknown for that peer (it blocks binding, creation and the
|
|
380
|
+
plan's managed check), and `ahub <peer>` writes every such row back unchanged,
|
|
381
|
+
replacing only its own valid row. A launcher recorded by 0.12.12 or older hashed
|
|
382
|
+
`ps` in its own TZ and locale (the pin came with #177): when the pinned signature
|
|
383
|
+
differs, the signature computed the unpinned way in the reader's environment is
|
|
384
|
+
compared too, and a match is live; a reader in another environment still reads
|
|
385
|
+
such a launcher as gone.
|
|
370
386
|
Restore reads this evidence in one place: the target's report, which counts only
|
|
371
387
|
when the target runs as the expected instance, then the recorded launcher. A
|
|
372
388
|
target that does not, a launcher that cannot be read, or a launcher record file
|
|
@@ -382,7 +398,18 @@ operation, and the runner keeps the disposition's own error. Abort and `next` de
|
|
|
382
398
|
(`abortRefusal`). `status`, abort and the runner's errors read the same live
|
|
383
399
|
state: every project not yet verified, its source or its target. A manifest
|
|
384
400
|
whose pid no longer exists reads as stopped, whatever protocol it names; probing
|
|
385
|
-
it would read unavailable forever.
|
|
401
|
+
it would read unavailable forever. So does a manifest whose pid now belongs to
|
|
402
|
+
another process (#226): from 0.12.21 `status.json` carries the daemon's process
|
|
403
|
+
signature (`pidSignature`, in the file only; the status reply is unchanged, so no
|
|
404
|
+
protocol bump), the registry claim carries it bound to the claiming instance, and
|
|
405
|
+
every ownership check (manifest, claim, runner, manager owner) goes through one
|
|
406
|
+
helper that reads live, gone or unknown. Recovery reads the claim from the
|
|
407
|
+
registry as it is now, never from the plan's frozen copy. Daemons no longer write
|
|
408
|
+
`hub.pid`; one an older daemon left is an unsigned legacy record. Records without
|
|
409
|
+
a signature give the answers they always did, so an unsigned claim whose pid was
|
|
410
|
+
reused still reads as starting: no command clears it (a hub started by 0.12.20 or
|
|
411
|
+
older that crashed before a reboot), and the operations guide gives the manual
|
|
412
|
+
clear after the process at that pid is checked. A stopped runtime also reports whose
|
|
386
413
|
unreleased restart snapshot its state directory holds.
|
|
387
414
|
An attached session is the target's report of that peer online with a thread
|
|
388
415
|
(Codex) or session (Claude, Pi) id.
|
|
@@ -404,7 +431,9 @@ An attached session is the target's report of that peer online with a thread
|
|
|
404
431
|
| project `prepared`, no `commitSent`, operation of a #215 coordinator | source stopped (crashed before any commit request) | blocks; the phase stays `prepared` (nothing was committed, so there is nothing to start from); not offered | abort if no effects, dispose | `<c> recovery abort <id>` without effects, else stop-and-archive (the lock refuses starting that hub by hand) |
|
|
405
432
|
| project `prepared` | source unavailable, starting, stopping or not inspected | as above when it reads again | none: abort (its hold may still stand) and stop-and-archive are refused until it reads | `<c> recovery status <id>` once it answers |
|
|
406
433
|
| project `prepared`, operation of an older coordinator (no `commitSent` written) | source not running, or not inspected | as its own runner does | dispose once it reads running, stopped or missing; abort neither offered nor accepted (it may have committed) | `<c> recovery status <id>` |
|
|
407
|
-
| project `started` or `peers-restored` | target stopped (a crash or reboot after it started),
|
|
434
|
+
| project `started` or `peers-restored` | target stopped (a crash or reboot after it started), this operation's snapshot kept | records the restart (dead instance, time), retires the dead instance's done `restored:<peer>` receipts, moves the project back to `stopped` and starts the target from the snapshot; once per resume | dispose | `the target stopped after it started; resume restarts it from this operation's snapshot` (`stopped again after restart <n> in this resume` when it stops again) |
|
|
435
|
+
| project `started` or `peers-restored` | target stopped, snapshot gone | blocks; not offered | dispose | `this operation's restart snapshot is gone, so nothing can start it` |
|
|
436
|
+
| `retired:<peer>` (a done restoration of a dead target instance) | Orca lists its terminal, or cannot be read | closed under the close receipt rules (`closedRetired:<peer>` `pending` until Orca no longer lists it); an unreadable inventory changes nothing | dispose | `close Orca terminal <handle> by hand` or `check it in Orca`, `then <c> recovery resume <id>` |
|
|
408
437
|
| project `stopped` | target stopped without this operation's snapshot (never committed) | blocks; not offered | dispose | `the target is stopped and this operation's restart snapshot is gone` |
|
|
409
438
|
| project `stopped`, `started` or `peers-restored` | target running unfenced, as another instance or another version | blocks; not offered | dispose | `daemon is not owned by this recovery operation` (or `daemon instance changed`, `target daemon version mismatch`) |
|
|
410
439
|
| any, at staging | preserved source or staged target changed, or (first staging of these bytes only) target protocol or recovery waivers refused | blocks; recorded as `final`, so resume is never offered again | abort if no effects, dispose | the refusal |
|
|
@@ -437,10 +466,39 @@ and its `next` entry says what that runner cannot do. Stop-and-archive stops a
|
|
|
437
466
|
target that speaks an older control protocol at that protocol (a `kill` fenced
|
|
438
467
|
by its instance), then waits for its manifest and registry claim as the
|
|
439
468
|
lifecycle stop does. The disposition and its audit are written before the first
|
|
440
|
-
act.
|
|
469
|
+
act. When the operation's coordinator predates #215, that same write sets the
|
|
470
|
+
receipt's `schema` to 2 (#227): an older runner never reads `disposition`, and an
|
|
471
|
+
older global `ahub recovery resume` still runs it, but every older runner and
|
|
472
|
+
abort refuses a schema other than 1 before it takes the lock or claims the
|
|
473
|
+
runner, so it exits having written nothing (an older `resume` still prints
|
|
474
|
+
`scheduled`; an older `status` still prints the receipt). A #215 coordinator's
|
|
475
|
+
operation keeps schema 1: its runner refuses a disposition itself, and a 0.12.20
|
|
476
|
+
CLI can still rerun its dispose. This release accepts schema 2 only with a
|
|
477
|
+
disposition, and the next abort or dispose that holds the runner claim moves a
|
|
478
|
+
schema-1 disposition 0.12.20 recorded on an older coordinator's operation to 2. A recovery launch of `ahub codex` records its launcher before the hub's
|
|
441
479
|
`start` round trip; an ordinary launch records it after, so a refused start never
|
|
442
480
|
replaces the record of a Codex already running.
|
|
443
481
|
|
|
482
|
+
#225: a target that stopped after it started is restarted only while its state
|
|
483
|
+
directory holds this operation's unreleased snapshot. The runner records the restart
|
|
484
|
+
in the project's receipt (`restarts`: the dead instance and the time) before acting,
|
|
485
|
+
moves each done `restored:<peer>` binding to `retired:<peer>`, clears the instance
|
|
486
|
+
and moves the project back to `stopped`, whose path starts the target from the
|
|
487
|
+
snapshot; the journal imports the snapshot only at revision 0, so the second start
|
|
488
|
+
continues from what the first wrote. `closed:<peer>`, `commitSent`, `fresh`, waivers
|
|
489
|
+
and the install flags stay. Restore closes each retired terminal (or finds it
|
|
490
|
+
absent) before relaunching that peer, and a peer whose retired session was an
|
|
491
|
+
accepted new one (fresh choice, fresh start, zero-turn Claude) is relaunched by that
|
|
492
|
+
id, which the operation-fenced waiver already covers, unless it has nothing to resume
|
|
493
|
+
(a Codex thread with no rollout, a Claude session with no transcript): that one starts
|
|
494
|
+
new under the waiver. Evidence reads the launch
|
|
495
|
+
records of every instance the operation started for the project, the dead ones
|
|
496
|
+
included, and a peer attached to the new instance without a session id is a session
|
|
497
|
+
of unknown identity, never "nothing attached". One restart per project per resume:
|
|
498
|
+
a target that stops again blocks with the restart count, so a crash loop never
|
|
499
|
+
spins unattended. Operations whose coordinator predates #225 keep refusing (their
|
|
500
|
+
own runner does), with stop-and-archive as the way out.
|
|
501
|
+
|
|
444
502
|
A Codex thread with no rollout is not blocked at the plan only when the hub saw
|
|
445
503
|
Codex start it (`native_thread` with `fresh`, logged by the adapter when it
|
|
446
504
|
adopts a thread) and logged no Codex `turn_start` while it was the adopted
|
package/docs/verified.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"documents": {
|
|
4
4
|
"README.md": {
|
|
5
|
-
"verifiedAgainst": "
|
|
5
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
6
6
|
"paths": [
|
|
7
7
|
"package.json",
|
|
8
8
|
"src/",
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
13
|
"docs/security.md": {
|
|
14
|
-
"verifiedAgainst": "
|
|
14
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
15
15
|
"paths": [
|
|
16
16
|
"src/",
|
|
17
17
|
"templates/"
|
|
18
18
|
]
|
|
19
19
|
},
|
|
20
20
|
"docs/operations.md": {
|
|
21
|
-
"verifiedAgainst": "
|
|
21
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
22
22
|
"paths": [
|
|
23
23
|
"package.json",
|
|
24
24
|
"src/",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
]
|
|
36
36
|
},
|
|
37
37
|
"docs/quickstart.md": {
|
|
38
|
-
"verifiedAgainst": "
|
|
38
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
39
39
|
"paths": [
|
|
40
40
|
"package.json",
|
|
41
41
|
"src/",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"docs/agent-notes/adapters.md": {
|
|
46
|
-
"verifiedAgainst": "
|
|
46
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
47
47
|
"paths": [
|
|
48
48
|
"src/adapters/",
|
|
49
49
|
"src/pi/",
|
|
@@ -52,11 +52,14 @@
|
|
|
52
52
|
"src/hub/lifecycle.ts",
|
|
53
53
|
"src/memory/capture.ts",
|
|
54
54
|
"scripts/benchmarks/teardown.ts",
|
|
55
|
-
"src/hub/daemon.ts"
|
|
55
|
+
"src/hub/daemon.ts",
|
|
56
|
+
"src/hub/permission-mode.ts",
|
|
57
|
+
"src/hub/tool-refusal.ts",
|
|
58
|
+
"src/cli/identity.ts"
|
|
56
59
|
]
|
|
57
60
|
},
|
|
58
61
|
"docs/agent-notes/benchmarks.md": {
|
|
59
|
-
"verifiedAgainst": "
|
|
62
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
60
63
|
"paths": [
|
|
61
64
|
"scripts/benchmarks/",
|
|
62
65
|
"test/benchmarks/",
|
|
@@ -68,7 +71,7 @@
|
|
|
68
71
|
]
|
|
69
72
|
},
|
|
70
73
|
"docs/agent-notes/budget.md": {
|
|
71
|
-
"verifiedAgainst": "
|
|
74
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
72
75
|
"paths": [
|
|
73
76
|
"src/hub/budget.ts",
|
|
74
77
|
"src/cli/statusline-tee.ts",
|
|
@@ -80,7 +83,7 @@
|
|
|
80
83
|
]
|
|
81
84
|
},
|
|
82
85
|
"docs/agent-notes/bus.md": {
|
|
83
|
-
"verifiedAgainst": "
|
|
86
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
84
87
|
"paths": [
|
|
85
88
|
"src/hub/bus.ts",
|
|
86
89
|
"src/hub/envelope.ts",
|
|
@@ -92,7 +95,7 @@
|
|
|
92
95
|
]
|
|
93
96
|
},
|
|
94
97
|
"docs/agent-notes/daemon.md": {
|
|
95
|
-
"verifiedAgainst": "
|
|
98
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
96
99
|
"paths": [
|
|
97
100
|
"src/hub/daemon.ts",
|
|
98
101
|
"src/hub/control-client.ts",
|
|
@@ -114,16 +117,18 @@
|
|
|
114
117
|
"src/cli/console.ts",
|
|
115
118
|
"src/cli/console-state.ts",
|
|
116
119
|
"src/cli/identity.ts",
|
|
117
|
-
"src/cli/identity-audit.ts"
|
|
120
|
+
"src/cli/identity-audit.ts",
|
|
121
|
+
"src/hub/registry.ts"
|
|
118
122
|
]
|
|
119
123
|
},
|
|
120
124
|
"docs/agent-notes/local-worker.md": {
|
|
121
|
-
"verifiedAgainst": "
|
|
125
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
122
126
|
"paths": [
|
|
123
127
|
"src/adapters/local-worker.ts",
|
|
124
128
|
"src/local/",
|
|
125
129
|
"src/memory/capture.ts",
|
|
126
|
-
"src/hub/facts.ts"
|
|
130
|
+
"src/hub/facts.ts",
|
|
131
|
+
"src/hub/permission-mode.ts"
|
|
127
132
|
]
|
|
128
133
|
},
|
|
129
134
|
"docs/agent-notes/models.md": {
|
|
@@ -136,7 +141,7 @@
|
|
|
136
141
|
]
|
|
137
142
|
},
|
|
138
143
|
"docs/agent-notes/tasks.md": {
|
|
139
|
-
"verifiedAgainst": "
|
|
144
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
140
145
|
"paths": [
|
|
141
146
|
"src/hub/tasks.ts",
|
|
142
147
|
"src/hub/board.ts",
|
|
@@ -147,11 +152,13 @@
|
|
|
147
152
|
"src/cli/main.ts",
|
|
148
153
|
"src/cli/preview.ts",
|
|
149
154
|
"src/hub/conductor.ts",
|
|
150
|
-
"src/hub/supervision.ts"
|
|
155
|
+
"src/hub/supervision.ts",
|
|
156
|
+
"src/hub/tool-refusal.ts",
|
|
157
|
+
"src/hub/daemon.ts"
|
|
151
158
|
]
|
|
152
159
|
},
|
|
153
160
|
"docs/agent-notes/tests.md": {
|
|
154
|
-
"verifiedAgainst": "
|
|
161
|
+
"verifiedAgainst": "c084278691cd0c978e8208df6ba9eaa62031d7f2",
|
|
155
162
|
"paths": [
|
|
156
163
|
"test/",
|
|
157
164
|
"scripts/check.sh",
|
|
@@ -161,7 +168,11 @@
|
|
|
161
168
|
"scripts/ci-gates.mjs",
|
|
162
169
|
"scripts/ci-reuse.mjs",
|
|
163
170
|
".github/workflows/check.yml",
|
|
164
|
-
".github/workflows/release.yml"
|
|
171
|
+
".github/workflows/release.yml",
|
|
172
|
+
"src/hub/child-process.ts",
|
|
173
|
+
"src/switchyard/sidecar.ts",
|
|
174
|
+
"src/local/sandbox.ts",
|
|
175
|
+
"src/models/mlx.ts"
|
|
165
176
|
]
|
|
166
177
|
}
|
|
167
178
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-hub",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.21",
|
|
4
4
|
"description": "Channel between Claude Code and the agent-hub daemon: peer messages from Codex, Kimi and the local worker arrive as channel events; hub_send replies.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Young Joon Lee",
|
|
@@ -15306,7 +15306,8 @@ function readControl(stateDir) {
|
|
|
15306
15306
|
instanceId: status.instanceId,
|
|
15307
15307
|
cwd: status.cwd,
|
|
15308
15308
|
protocol: status.protocol,
|
|
15309
|
-
pid: status.pid
|
|
15309
|
+
pid: status.pid,
|
|
15310
|
+
...typeof status.pidSignature === "string" && status.pidSignature ? { pidSignature: status.pidSignature } : {}
|
|
15310
15311
|
};
|
|
15311
15312
|
} catch {
|
|
15312
15313
|
return;
|
|
@@ -15403,7 +15404,7 @@ class ControlClient {
|
|
|
15403
15404
|
// package.json
|
|
15404
15405
|
var package_default = {
|
|
15405
15406
|
name: "@staix/agent-hub",
|
|
15406
|
-
version: "0.12.
|
|
15407
|
+
version: "0.12.21",
|
|
15407
15408
|
description: "Native multi-agent hub: Claude Code, Codex, Kimi Code, Pi and local inference as peers in one project",
|
|
15408
15409
|
license: "MIT",
|
|
15409
15410
|
type: "module",
|