@staix/agent-hub 0.34.1 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +35 -6
- package/docs/adding-an-ai-tool.md +2 -2
- package/docs/addons/claude-mem.md +4 -4
- package/docs/addons/open-code-review.md +1 -1
- package/docs/agent-notes/README.md +6 -0
- package/docs/agent-notes/adapters.md +9 -5
- package/docs/agent-notes/budget.md +1 -1
- package/docs/agent-notes/bus.md +1 -1
- package/docs/agent-notes/daemon.md +4 -3
- package/docs/agent-notes/local-worker.md +1 -1
- package/docs/agent-notes/models.md +2 -0
- package/docs/agent-notes/tasks.md +1 -1
- package/docs/agent-notes/tests.md +5 -0
- package/docs/design/adapters.md +110 -2
- package/docs/design/agent-hub-architecture.md +63 -1
- package/docs/design/agent-hub.md +6 -0
- package/docs/design/bus.md +18 -0
- package/docs/design/execution-reference.md +146 -0
- package/docs/design/task-board.md +10 -0
- package/docs/dogfood.md +33 -12
- package/docs/events.md +38 -20
- package/docs/memory.md +21 -7
- package/docs/operations.md +539 -24
- package/docs/quickstart.md +12 -4
- package/docs/research.md +71 -13
- package/docs/roles.md +1 -1
- package/docs/sdlc.md +9 -7
- package/docs/security.md +87 -11
- package/docs/smoke.md +14 -0
- package/docs/specs/2026-09-19-agent-hub-design.md +8 -3
- package/docs/verification/2026-11-07-compat-python-startup-1248.md +51 -0
- package/docs/verification/2026-11-07-compat-receipt-harness-1248.md +105 -0
- package/docs/verification/2026-11-07-compat-receipt-producers-1248.md +96 -0
- package/docs/verification/2026-11-07-compat-workflow-1248.md +94 -0
- package/docs/verification/2026-11-07-daemon-startup-1232.md +169 -0
- package/docs/verification/2026-11-07-jcode-receipt-reconstruction-1248.md +118 -0
- package/docs/verification/2026-11-07-kimi-delayed-usage.md +34 -0
- package/docs/verification/2026-11-07-kimi-review-watch-1284.md +115 -0
- package/docs/verification/2026-11-08-agy-1.5.3.md +96 -0
- package/docs/verification/2026-11-08-agy-acp-t0.md +56 -0
- package/docs/verification/2026-11-08-hub-visual-1058.md +161 -0
- package/docs/verification/2026-11-08-jcode-0991-model-setter-1317.md +143 -0
- package/docs/verification/2026-11-08-kimi-252-model-setter-1317.md +137 -0
- package/docs/verification/2026-11-08-kimi-tui-completion-1282.md +45 -0
- package/docs/verification/2026-11-08-kimi-wire-yield-1283.md +31 -0
- package/docs/verification/2026-11-08-live-model-override-1317.md +250 -0
- package/docs/verification/2026-11-08-qwen-0269-acp.md +138 -0
- package/docs/verification/2026-11-08-qwen-0269-model-setter-1317.md +91 -0
- package/docs/verification/2026-11-09-0.35.0.md +129 -0
- package/docs/verification/2026-11-09-headless-records-1320.md +157 -0
- package/docs/verification/claude-permission-transport-native.py +10 -3
- package/docs/verification/claude-shell-wrapper-native.py +8 -8
- package/docs/verified.json +245 -15
- package/package.json +3 -3
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/kimi-hook.js +20397 -0
- package/plugins/agent-hub/kimi-review-policy-worker.js +217 -0
- package/plugins/agent-hub/server.js +2701 -664
- package/scripts/check-docs.mjs +12 -1
- package/src/adapters/acp-model-policy.ts +56 -0
- package/src/adapters/acp.ts +175 -5
- package/src/adapters/agy/entry.ts +8 -5
- package/src/adapters/agy/hooks.ts +65 -15
- package/src/adapters/channel-peer.ts +33 -1
- package/src/adapters/claude-implementer.ts +16 -3
- package/src/adapters/codex-appserver.ts +118 -8
- package/src/adapters/codex-review-isolation.ts +3 -1
- package/src/adapters/compat.ts +11 -6
- package/src/adapters/definitions/builtin-metadata.ts +8 -1
- package/src/adapters/definitions/native-cli-entry-kimi.ts +76 -7
- package/src/adapters/definitions/native-cli-preview-common.ts +2 -2
- package/src/adapters/definitions/native-cli-preview-kimi.ts +9 -2
- package/src/adapters/definitions/reviewer-variants.ts +3 -1
- package/src/adapters/kimi-review-policy-worker.js +2 -0
- package/src/adapters/kimi-review-policy-worker.ts +85 -0
- package/src/adapters/kimi-review-policy.ts +68 -0
- package/src/adapters/kimi-review.ts +41 -41
- package/src/adapters/kimi-tui-facts.ts +153 -0
- package/src/adapters/kimi-wire-usage.ts +33 -8
- package/src/adapters/local-worker.ts +59 -20
- package/src/adapters/model-token.ts +3 -0
- package/src/adapters/pi.ts +27 -5
- package/src/adapters/registry-types.ts +34 -3
- package/src/adapters/registry.ts +1 -0
- package/src/adapters/reviewer-policy-watch.ts +86 -0
- package/src/adapters/reviewer-print.ts +80 -18
- package/src/cli/agents.ts +1 -1
- package/src/cli/facts-hook.ts +4 -2
- package/src/cli/help.ts +3 -2
- package/src/cli/identity.ts +3 -0
- package/src/cli/kimi-facts-hook.ts +11 -0
- package/src/cli/kimi-plugin.ts +157 -0
- package/src/cli/main.ts +48 -9
- package/src/cli/model.ts +52 -0
- package/src/cli/output.ts +23 -1
- package/src/cli/reset.ts +1 -1
- package/src/cli/status-lines.ts +8 -4
- package/src/hub/budget.ts +1 -1
- package/src/hub/bus.ts +40 -2
- package/src/hub/code-facts.ts +10 -3
- package/src/hub/completions.ts +3 -1
- package/src/hub/config-apply.ts +2 -1
- package/src/hub/control-client.ts +1 -1
- package/src/hub/daemon.ts +1050 -106
- package/src/hub/deliverable-files.ts +38 -5
- package/src/hub/dogfood-profile.ts +1 -1
- package/src/hub/envelope.ts +1 -1
- package/src/hub/events.ts +28 -18
- package/src/hub/execution-lineage.ts +120 -0
- package/src/hub/execution-reference.ts +36 -0
- package/src/hub/hub-tools.ts +21 -2
- package/src/hub/instances.ts +4 -3
- package/src/hub/kimi-events.ts +46 -0
- package/src/hub/kimi-usage.ts +132 -29
- package/src/hub/lifecycle.ts +31 -15
- package/src/hub/limits.ts +13 -4
- package/src/hub/manager.ts +15 -2
- package/src/hub/memory-policy.ts +2 -1
- package/src/hub/memory-sync-attestation.ts +54 -0
- package/src/hub/memory-sync-state.ts +20 -5
- package/src/hub/model-overrides.ts +115 -0
- package/src/hub/native-hook-launch.ts +12 -3
- package/src/hub/operational-view.ts +2 -2
- package/src/hub/peers.ts +27 -0
- package/src/hub/permission-mode.ts +1 -1
- package/src/hub/person-figures.ts +88 -0
- package/src/hub/report.ts +38 -4
- package/src/hub/research-dataset.ts +158 -0
- package/src/hub/research-memory.ts +68 -0
- package/src/hub/research-quality.ts +118 -0
- package/src/hub/research-record.ts +279 -0
- package/src/hub/research.ts +126 -27
- package/src/hub/restart.ts +14 -0
- package/src/hub/settings.ts +3 -0
- package/src/hub/startup-event-seeds.ts +51 -0
- package/src/hub/startup-readiness.ts +65 -0
- package/src/hub/startup-timing.ts +38 -0
- package/src/hub/tasks.ts +29 -9
- package/src/hub/ui.ts +9 -5
- package/src/hub/visual-assets.ts +50 -0
- package/src/hub/visual.ts +257 -0
- package/src/memory/brief.ts +169 -14
- package/src/memory/capture.ts +2 -1
- package/src/memory/recall.ts +46 -5
- package/src/memory/record-provenance.ts +82 -0
- package/src/memory/records.ts +116 -0
- package/src/models/route/adec.ts +190 -0
- package/src/models/route/config.ts +37 -3
- package/src/models/route/decision-evidence.ts +83 -0
- package/src/models/route/decision.ts +143 -0
- package/src/models/route/runtime.ts +13 -6
- package/src/ui/index.html +134 -6
- package/src/ui/plugin.ts +65 -4
- package/templates/AGENTS.block.md +1 -1
- package/templates/config.json +1 -1
- package/templates/profiles/general.json +1 -1
- package/templates/profiles/research.json +1 -1
- package/templates/profiles/writing.json +1 -1
package/docs/operations.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Operations guide
|
|
2
2
|
|
|
3
|
-
This guide describes ahub 0.
|
|
3
|
+
This guide describes ahub 0.35.0 and control protocols 16 through 17. Live verification
|
|
4
4
|
results and remaining prerequisites are recorded separately in [the smoke ledger](smoke.md).
|
|
5
5
|
|
|
6
6
|
## Agent-operated live verification
|
|
@@ -1040,8 +1040,8 @@ plugin stale when the module changed after setup, so run `ahub setup` again afte
|
|
|
1040
1040
|
|
|
1041
1041
|
## Install and start
|
|
1042
1042
|
|
|
1043
|
-
Use Bun 1.4.2 or newer. Source checks and CI use the version pinned in
|
|
1044
|
-
`.bun-version` (currently 1.4.2). Install the released package and install its Claude
|
|
1043
|
+
Use Bun <!-- facts:bun-floor -->1.4.2<!-- /facts:bun-floor --> or newer. Source checks and CI use the version pinned in
|
|
1044
|
+
`.bun-version` (currently <!-- facts:bun-pinned -->1.4.2<!-- /facts:bun-pinned -->). Install the released package and install its Claude
|
|
1045
1045
|
channel plugin:
|
|
1046
1046
|
|
|
1047
1047
|
```bash
|
|
@@ -1055,6 +1055,20 @@ ahub up
|
|
|
1055
1055
|
`ahub init` writes the project configuration and managed instruction blocks.
|
|
1056
1056
|
Run it after an upgrade when those blocks need refreshing.
|
|
1057
1057
|
|
|
1058
|
+
`ahub up` waits for authenticated readiness. After 12 seconds, a verified live
|
|
1059
|
+
child that is still pending produces a `still starting, pid N` message on stderr;
|
|
1060
|
+
the CLI keeps waiting and confirms the retained runtime when it becomes ready.
|
|
1061
|
+
At 120 seconds it reports unconfirmed readiness and exits unsuccessfully, leaving
|
|
1062
|
+
the daemon running. Run `ahub status` and inspect `hub.log` before another start.
|
|
1063
|
+
An owned child observed to exit before readiness produces an error; a cancelled
|
|
1064
|
+
operation cannot confirm startup.
|
|
1065
|
+
|
|
1066
|
+
Each completed daemon startup writes one `startup timings ms:` line to `hub.log`,
|
|
1067
|
+
with fixed phase names and durations. The three event-seed consumers share one
|
|
1068
|
+
lossless streaming pass; abandoned snapshot bodies are not read for startup.
|
|
1069
|
+
The [startup receipt](verification/2026-11-07-daemon-startup-1232.md) separates
|
|
1070
|
+
seed I/O from bounded usage-rollup I/O and records the isolated measurements.
|
|
1071
|
+
|
|
1058
1072
|
Settings flags (#1100) set the main project settings without a file edit.
|
|
1059
1073
|
`--agents <a,b,...|none>` (`start.agents`) and `--autonomy inherit|off` (whether a
|
|
1060
1074
|
new project inherits the machine autonomy preset) go to the untracked
|
|
@@ -1655,6 +1669,7 @@ token counts, never message bodies or task titles.
|
|
|
1655
1669
|
ahub report --since 7d # turns, busy time and tokens per peer, messages, overlaps, task events
|
|
1656
1670
|
ahub report --since 7d --json # the same numbers as JSON
|
|
1657
1671
|
ahub report --by task # tokens, turns and wall time per task and class, with the unattributed share
|
|
1672
|
+
# and, from #1278, what the person was asked per task (permissions, questions, completions, CLI refusals, minutes from recorded latencies only), with the unattributed remainder apart
|
|
1658
1673
|
ahub export --since 24h # the raw events as JSON lines, for your own analysis
|
|
1659
1674
|
ahub report --dogfood [--since 7d|<iso>] [--json] # read-only scorecard: flow, quality, cost, delivery, performance, adoption
|
|
1660
1675
|
```
|
|
@@ -1716,13 +1731,15 @@ redistributed (rules: [events](events.md#per-task-usage-reports)).
|
|
|
1716
1731
|
## Research records
|
|
1717
1732
|
|
|
1718
1733
|
With `"research": { "enabled": true }` in `.agenthub/config.json` (off by default), the hub keeps one record per
|
|
1719
|
-
approved
|
|
1720
|
-
checks, tokens and time per peer and model,
|
|
1734
|
+
task that reaches a terminal state (approved or cancelled) in `~/.agenthub/research/`, shared by every project that opts in:
|
|
1735
|
+
outcome, review rounds and findings, delivery and merge figures, rework, failed checks, tokens and time per peer and model,
|
|
1736
|
+
never task or message text ([schema](research.md)). Unknown values are null and counted, never zero.
|
|
1721
1737
|
|
|
1722
1738
|
```bash
|
|
1723
1739
|
ahub research --since 30d # success, first-pass, rework and check-failure rates; tokens and wall time per task
|
|
1724
1740
|
ahub research --all --json # every opted-in project on this machine
|
|
1725
1741
|
ahub research export --format csv # the records, for your own analysis
|
|
1742
|
+
ahub research export --dataset ~/research-out [--all] # per-project tasks.jsonl, manifest.json, quality.json: family names only, to a directory in your home outside every project
|
|
1726
1743
|
ahub research backfill # build this project's records once from events.jsonl
|
|
1727
1744
|
ahub task label 12 reverted # a later verdict (ok, regressed, reverted, incomplete, wrong, abandoned)
|
|
1728
1745
|
```
|
|
@@ -1824,7 +1841,7 @@ ahub memory forget 1a2b3c4d # a person's; also promote, demote, sup
|
|
|
1824
1841
|
|
|
1825
1842
|
`"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
|
|
1826
1843
|
|
|
1827
|
-
The exact-pinned `@staix/agent-mem` 0.
|
|
1844
|
+
The exact-pinned `@staix/agent-mem` 0.23.1 resolves `AMEM_HOME`, then `$AGENTHUB_HOME/memory`, then `~/.agenthub/memory`. An absent `M/profile.json` selects shared v1; an explicit generation selects `M/generations/G` with the package's readonly legacy bridge. All daemon memory consumers and the hub memory/goal CLI use that selected profile. Invalid metadata or a missing selected generation makes native memory unavailable while the bus and board continue; there is no fallback to legacy writes. Inspect the daemon's memory binding/availability before interpreting missing memory as an empty store.
|
|
1828
1845
|
|
|
1829
1846
|
The daemon checks its selector at hub operation entry and before candidate/counter writes. It does not hot-switch handles or provide an atomic fence against selection changes during an in-flight core call. Quiesce consumers and close their handles before migration or selection changes; reopen through the supported session-preserving lifecycle afterward. Candidate/counter storage remains `M/candidates.db`, independent of `G`; since agent-mem 0.7.0 `amem review` also lists and accepts candidates on a selected generation. Every running hub using this home needs an authenticated receipt: a matching ready binding, or a generation-capable unbound receipt (`disabled` when native memory is off, `unavailable` when opening failed) proving it holds no memory handle. An unbound daemon and zero running hubs are quiesced for memory; a stale bound handle, unreadable registry or unknown runtime is not ready. Existing JSON memory/goal results remain unchanged; the additive binding receipt belongs to daemon status, profile-check and the decay object. This source integration does not authorize installing a new runtime, migrating real memory, restarting sessions or claiming real-machine sync/capture receipts. Migration/deactivation and their limits belong to [agent-mem](https://github.com/STAIxBWLB/agent-mem); see [the hub profile contract](memory.md#selected-memory-profile).
|
|
1830
1847
|
|
|
@@ -2442,6 +2459,73 @@ roster setting do not change running participation: they take effect at the next
|
|
|
2442
2459
|
hub start. The tracked config can provide defaults and config.local.json can
|
|
2443
2460
|
override them.
|
|
2444
2461
|
|
|
2462
|
+
## Live peer model overrides (#1317)
|
|
2463
|
+
|
|
2464
|
+
From a plain person terminal, select the next model of a supported peer without
|
|
2465
|
+
restarting the peer or reloading project configuration:
|
|
2466
|
+
|
|
2467
|
+
```bash
|
|
2468
|
+
ahub model set claude-impl claude-sonnet-5-5
|
|
2469
|
+
ahub model set codex gpt-5.1-codex
|
|
2470
|
+
ahub model clear claude-impl
|
|
2471
|
+
ahub model list
|
|
2472
|
+
ahub model list --json
|
|
2473
|
+
```
|
|
2474
|
+
|
|
2475
|
+
Use a model id available through the peer's existing provider.
|
|
2476
|
+
Model ids are one bounded token: letters, digits and `._:/@+-`, at most 128 bytes,
|
|
2477
|
+
no spaces and no leading dash. Agent shells and every hub-tool caller are
|
|
2478
|
+
refused, including list; a conductor role does not grant person authority.
|
|
2479
|
+
The dashboard Peers action uses a person settings session and preview/confirm,
|
|
2480
|
+
not an agent command or an ordinary dashboard permission escalation.
|
|
2481
|
+
|
|
2482
|
+
An override is desired runtime state in `hub.db`. It survives daemon restart;
|
|
2483
|
+
`ahub reset` clears it with runtime state. Precedence is override, instance
|
|
2484
|
+
model, launch model, then native default where that surface supports them.
|
|
2485
|
+
Clear restores the existing lower-priority selection. For Codex app-server,
|
|
2486
|
+
an explicit client model always wins over hub injection. A `turn/start` model
|
|
2487
|
+
becomes the native thread default, so clear may retain that current default;
|
|
2488
|
+
it does not recover an earlier model. Raw/pull-only native TUI attachments remain
|
|
2489
|
+
unsupported. A retained former override is labelled `native thread default (was override)`;
|
|
2490
|
+
a rejected start leaves the next start free to sample a corrected selection.
|
|
2491
|
+
The model and its source appear in `ahub status` and JSON output. An unknown native default remains
|
|
2492
|
+
unknown. `pending next turn` means the desired value has not been acknowledged
|
|
2493
|
+
at an eligible boundary; it does not claim the current turn changed models.
|
|
2494
|
+
|
|
2495
|
+
Changing a desired value during a turn leaves that turn unchanged. Steering and
|
|
2496
|
+
local tool rounds keep the captured selection. If the person changes it twice
|
|
2497
|
+
before the next turn, only the last desired value is selected there. A stale
|
|
2498
|
+
callback cannot mark a newer desired value or another adapter owner applied.
|
|
2499
|
+
|
|
2500
|
+
T1 supports headless Claude implementer turns, supported Codex app-server turns,
|
|
2501
|
+
fresh codex-review spawns, the local worker and Pi. Native account/provider
|
|
2502
|
+
availability is still the backend's responsibility. Headless Kimi Code CLI 2.5.2
|
|
2503
|
+
also supports next-turn selection through its receipt-backed ACP model setter.
|
|
2504
|
+
It requires the existing native identity admission, an exact-version receipt,
|
|
2505
|
+
an owned current session and advertised model choices. Clear restores the
|
|
2506
|
+
validated session baseline. Kimi reviewer isolation and version qualification
|
|
2507
|
+
are separate and unchanged.
|
|
2508
|
+
|
|
2509
|
+
Jcode, Qwen, other Kimi versions and native TUI forms remain `unsupported live`.
|
|
2510
|
+
The [Jcode headless fixture](verification/2026-11-08-jcode-0991-model-setter-1317.md)
|
|
2511
|
+
passes, but does not fence a shared TUI turn across native failover. The
|
|
2512
|
+
[Qwen 0.26.9 setter fixture](verification/2026-11-08-qwen-0269-model-setter-1317.md)
|
|
2513
|
+
fails restoration of the original model. Neither enables a production setter.
|
|
2514
|
+
A refused set writes no new override and never restarts a process. Follow the
|
|
2515
|
+
reported cause and `ahub restart <peer>` guidance for unsupported forms.
|
|
2516
|
+
|
|
2517
|
+
This does not make `instances.*.model` or `*_cmd` live or editable by agents.
|
|
2518
|
+
Their existing machine-local tier 3 confirmation and restart behavior remains.
|
|
2519
|
+
The plural `ahub models` still manages the existing local model service; it is
|
|
2520
|
+
separate from the singular per-peer `ahub model` command. `model_change` records
|
|
2521
|
+
ids and the next-turn boundary, never prompts or credentials.
|
|
2522
|
+
|
|
2523
|
+
Model display is bounded to 512 local identities. If legacy sessions exceed the
|
|
2524
|
+
view budget, list refuses explicitly and status/dashboard mark model data
|
|
2525
|
+
unavailable; they never call a truncated list complete. Close unused native
|
|
2526
|
+
sessions, clear obsolete overrides and follow the restart guidance. Single-peer
|
|
2527
|
+
set/clear remains usable and no process is restarted automatically.
|
|
2528
|
+
|
|
2445
2529
|
## Settings from the dashboard and the terminal
|
|
2446
2530
|
|
|
2447
2531
|
In `ahub console`, press `6` for Settings. Existing operational-tab arrow cycling
|
|
@@ -2990,6 +3074,14 @@ Read quota and approve tools
|
|
|
2990
3074
|
in Kimi's own TUI; a person can pause the hub queue by hand. End the native terminal
|
|
2991
3075
|
session there, not with `ahub stop kimi`.
|
|
2992
3076
|
|
|
3077
|
+
On Kimi 2.5.2 (compat entry `kimi-tui`), the launcher also installs a launch-scoped
|
|
3078
|
+
plugin under `plugins/managed/agent-hub` in the Kimi home (`KIMI_CODE_HOME`, default
|
|
3079
|
+
`~/.kimi-code`) and removes it when the TUI exits (#1282). Its hooks let a turn you
|
|
3080
|
+
started there settle into a result (`ahub results`), always private, once the native
|
|
3081
|
+
transcript shows the turn ended and no native background task is running or unknown. This adds no push,
|
|
3082
|
+
steer, watchdog or quota handoff. Another Kimi version, or a plugin setup that
|
|
3083
|
+
fails, prints the cause and launches the plain TUI without completion receipts.
|
|
3084
|
+
|
|
2993
3085
|
Automatic routing never picks a pull-only owner or reviewer, even as the only
|
|
2994
3086
|
candidate. A proposer can name the owner or claim its own task; a person or the
|
|
2995
3087
|
conductor can name an owner or reviewer with
|
|
@@ -3099,6 +3191,8 @@ Unread quota resume notices are coalesced without losing their public task moves
|
|
|
3099
3191
|
|
|
3100
3192
|
A refused prompt with no acceptance or activity is requeued without a review hold. At the estimated reset it is tried again; another quota refusal pauses it again without consuming the poison-envelope retry count. Work that already started remains held for review even while its open tasks move to other peers. After the quota reset its queue stays held: inspect `ahub queue show <delivery-id>` and the associated task, then choose `ahub queue resolve <delivery-id> --action completed|retry|discard --reason "<text>"`. Do not retry work that another owner already took over without inspecting it. If the hub cannot confirm the pause, the refusal is also held instead of spending retries. Other errors keep their ordinary review behavior. Only the observed Kimi 5-hour text is recognised; weekly/monthly limits and other ACP vendors, including Qwen, remain unverified. The recognised text and its provenance live in `src/adapters/acp-quota.ts`.
|
|
3101
3193
|
|
|
3194
|
+
The gate is `budget.gate`, 0.99 by default (#1292; 0.9 before). A peer whose fresh quota window reaches the gate is asked to checkpoint, then paused and its work handed over. It resumes when every fresh window is under the gate minus 0.1, or at the reset. A release cut is also held while any window has no more headroom than 1 minus the gate. At 0.99 a soft pause leaves about 1% of the window for the checkpoint turn; a provider's hard refusal still pauses at once. `budget.gate` is a registered setting (a number from 0 to 1): set it with `ahub settings set budget.gate <value>` in a terminal or in an `ahub ui --settings` session. An ordinary dashboard session and the conductor cannot set it. The value goes to `config.local.json`; the running hub uses it from the next quota reading, with no restart. A project created before #1292 has `"gate": 0.9` in its tracked `.agenthub/config.json` (the init template wrote it), and that value overrides the default: remove the key there to follow the default, or set the machine-local value.
|
|
3195
|
+
|
|
3102
3196
|
Quota also shapes routing and handoffs:
|
|
3103
3197
|
|
|
3104
3198
|
- Among peers a task could go to, those with quota readings are ordered by
|
|
@@ -3549,7 +3643,119 @@ The data-only [manifest](../scripts/compat-receipts/manifest.json) and [per-leg
|
|
|
3549
3643
|
|
|
3550
3644
|
Optional model/TUI behavior explicitly left unverified by a model-free receipt is not a new admission leg. `codex-review` requires its separately authorized model-backed tool-call proof. `agy` has no public install source. `qwen-dual` requires real-model and TUI work and its current receipt does not name the OS. The manifest records acquisition metadata separately from historical native-binary evidence; no CLI installation or COMPAT change is made by this audit.
|
|
3551
3645
|
|
|
3552
|
-
For CI-opened PRs, the person
|
|
3646
|
+
For CI-opened PRs, the person selected `GITHUB_TOKEN` with explicit `check.yml` dispatch on `compat/<id>-<version>` (2026-11-07). The publisher needs `actions: write` for dispatch in addition to its branch, PR and issue permissions. No GitHub App credentials are used. Dispatch supplies exact-head check evidence; it does not trigger the separate PR-only closing-refs/routing-receipt workflows. The T0 audit retains the alternative App-token trade-offs as history. Current [GitHub documentation](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow) also describes approval-required PR runs for GITHUB_TOKEN automation; that is not unattended CI. See the audit for permissions, queue and gate trade-offs.
|
|
3647
|
+
|
|
3648
|
+
### Automated receipt workflow (#1248 T2)
|
|
3649
|
+
|
|
3650
|
+
After merge, `agent-compat.yml` runs daily and can be dispatched with `dry: true`
|
|
3651
|
+
(the manual default). The watcher emits validated ahead/version and verified-ID
|
|
3652
|
+
JSON directly; matrix construction never parses report prose. At most eight IDs
|
|
3653
|
+
are considered, with two hosted jobs at once. An unspecified manifest OS stays
|
|
3654
|
+
not-run rather than receiving an invented native-platform proof.
|
|
3655
|
+
|
|
3656
|
+
The candidate matrix has only `contents: read`, no supplied secrets, checkout
|
|
3657
|
+
credentials disabled and a 20-minute job bound. It runs the disposable harness and
|
|
3658
|
+
uploads JSON/Markdown even for failed or not-run legs. A separate trusted read-only
|
|
3659
|
+
job validates the summaries and builds the embedded COMPAT bundle from repository
|
|
3660
|
+
source. It never imports candidate JS or Markdown. The publisher downloads that
|
|
3661
|
+
job's immutable artifact ID and validates descriptors, byte hashes, identities,
|
|
3662
|
+
complete leg sets and trusted manifest policy again.
|
|
3663
|
+
|
|
3664
|
+
The candidate CLI and receipt writer share a job and OS user. A malicious release
|
|
3665
|
+
could overwrite its own `summary.json` before upload with a well-formed eligible
|
|
3666
|
+
forgery; preparation cannot detect that forgery from the data alone. An eligible
|
|
3667
|
+
receipt is a compatibility signal, not a security attestation of the release.
|
|
3668
|
+
The person's PR and release review is the real admission gate; the automation
|
|
3669
|
+
never merges its verification PR.
|
|
3670
|
+
|
|
3671
|
+
Only the publisher has contents/PR/issues write and Actions dispatch permission.
|
|
3672
|
+
It executes first-party Node code and `gh` REST calls, with no package install,
|
|
3673
|
+
build or candidate execution. All required legs must pass and trusted `autoAdmit`
|
|
3674
|
+
must allow the ID; artifact `eligible` alone is not evidence. It changes only the
|
|
3675
|
+
exact COMPAT row, its receipt and prepared plugin assets on `compat/<id>-<version>`.
|
|
3676
|
+
Existing bot branches are checked for manual drift; unknown collisions refuse,
|
|
3677
|
+
updates append without force, and verification PRs are never auto-merged. A newer
|
|
3678
|
+
same-ID PR supersedes an older one only after the replacement and its check
|
|
3679
|
+
dispatch succeed.
|
|
3680
|
+
|
|
3681
|
+
Other results update closed-cause receipt blocks in the exact-title drift issue.
|
|
3682
|
+
Confirmed verified IDs remove their stale blocks, while still-drifting or unknown
|
|
3683
|
+
IDs retain their evidence. Report text never supplies those identities. Dry mode
|
|
3684
|
+
still performs isolated proof and read-only build/artifact work, then prints the
|
|
3685
|
+
planned GitHub changes without creating/updating branches, PRs, labels or issues.
|
|
3686
|
+
It is not native compatibility qualification on the person's Mac.
|
|
3687
|
+
|
|
3688
|
+
See the [T2 verification report](verification/2026-11-07-compat-workflow-1248.md)
|
|
3689
|
+
for the data/credential boundary, fixtures and final committed-head evidence.
|
|
3690
|
+
|
|
3691
|
+
### Isolated receipt harness (#1248 T1)
|
|
3692
|
+
|
|
3693
|
+
Run `bun scripts/compat-receipt.ts <id> <exact-version> --out <new-owned-directory> --disposable-runner`
|
|
3694
|
+
from the checkout on a GitHub-hosted runner or disposable Linux container. The
|
|
3695
|
+
explicit flag is required; a local personal Mac is refused even with a temporary
|
|
3696
|
+
HOME. The runner VM/container must be destroyed after the job. The command writes `summary.json` and `receipt.md` without
|
|
3697
|
+
changing COMPAT, trust on this machine, or any workflow. Its exit codes are 0 for
|
|
3698
|
+
a completed pass, 1 for failure, 3 for required work left not-run, and 2 for invalid
|
|
3699
|
+
input/output. `eligible` also requires the manifest's admission policy; a pass
|
|
3700
|
+
alone never overrides the Codex/agy policy or a required model/TUI leg.
|
|
3701
|
+
|
|
3702
|
+
The installer binds exact npm metadata and SRI before installing the verified
|
|
3703
|
+
local tarball into its private prefix, with empty user/global npm configs and a
|
|
3704
|
+
private cache. Release assets must match their tagged SHA-256 digest and checksum
|
|
3705
|
+
before bounded extraction; absolute/traversal/link/nonregular archive entries and
|
|
3706
|
+
size/count excesses refuse. No global installer or caller credential environment
|
|
3707
|
+
is used. Normal npm lifecycle behavior is not silently disabled; this does not
|
|
3708
|
+
certify an unreviewed lifecycle proof. Isolation uses fresh HOME/XDG/tool homes and
|
|
3709
|
+
an allowlisted environment, not a claim of kernel confinement for every installer.
|
|
3710
|
+
|
|
3711
|
+
Proof APIs load in a separate worker after that environment is established. The
|
|
3712
|
+
Codex backend's real production preparation is reused, including empty and
|
|
3713
|
+
ambient fixtures; its returned model `exec` command is never started. Kimi private
|
|
3714
|
+
configuration, exact host inventory and broker refusals are separate from native
|
|
3715
|
+
tool dispatch. Committed Claude transport/wrapper producers are imported through
|
|
3716
|
+
`runpy`, with optional exact-version/runtime-path inputs; their historical defaults
|
|
3717
|
+
and behavior assertions remain intact. No prepare evidence-description string is
|
|
3718
|
+
used as an execution-time proof.
|
|
3719
|
+
|
|
3720
|
+
| Proof family | T1 can run | Explicit not-run work |
|
|
3721
|
+
| --- | --- | --- |
|
|
3722
|
+
| Codex reviewer | Committed production prepare, actual metadata/native-canary checks and launch configuration assertions | Model-backed hub call, separate control artifact and human source review |
|
|
3723
|
+
| Kimi reviewer | Committed prepare/inventory/broker plus promoted native two-tool loop, Write positive/negative controls, preload guard and producer group cleanup | Human source review; unsupported native platform |
|
|
3724
|
+
| Claude implementer | Committed Write/Bash/rewrite and host-wrapper producer groups | Human upstream-impact review; unsupported launcher forms |
|
|
3725
|
+
| Pi | Artifact acquisition only in this core | Historical top-level producer needs import-safe/candidate-version extraction |
|
|
3726
|
+
| Qwen ACP | Promoted ACP identity/session/mapped-mode and actual published permission-handler producers, preload controls and group cleanup | Human lifecycle/source review; Linux does not replace required macOS arm64 |
|
|
3727
|
+
| Jcode | Reconstructed isolated serve/ACP/MCP, fixed-stream steering, telemetry and owned-group checks | Human source comparison; native macOS qualification remains unverified. The 0.99.1 Linux control is not qualified: telemetry identity and strict persisted-context binding fail; see the [reconstruction receipt](verification/2026-11-07-jcode-receipt-reconstruction-1248.md) |
|
|
3728
|
+
| agy and qwen-dual | Policy and unavailable/manual-leg reporting | No public agy installer; account/model/TUI or unspecified-platform legs |
|
|
3729
|
+
|
|
3730
|
+
Every manifest leg appears as pass, fail or not-run with a cause and next step.
|
|
3731
|
+
Missing producers are not inferred from configuration or other host tests. Partial
|
|
3732
|
+
receipts cannot qualify a candidate while required work is missing. Source/lifecycle
|
|
3733
|
+
semantic review is not a fetched-diff pass. Synthetic loopback fixture sentinels are
|
|
3734
|
+
not real provider API keys; parent account/model variables never reach a worker.
|
|
3735
|
+
|
|
3736
|
+
Default execution deadlines are 15 minutes overall, 3 minutes for installation
|
|
3737
|
+
and 2 minutes per proof-worker/group. Owned-process teardown has a separately
|
|
3738
|
+
bounded 10-second allowance, included in the JSON wall-time bounds. Output verification/publication has a
|
|
3739
|
+
separate 16-second allowance included in the total; elapsed time is sampled before
|
|
3740
|
+
publication. The summary
|
|
3741
|
+
separates `ownedStopConfirmed` from `processCleanup: proven|unproven` and gives its
|
|
3742
|
+
reason. An empty leader process group cannot prove lifetime cleanup: a helper can
|
|
3743
|
+
detach into a new group with ignored pipes and survive its launcher. Detected
|
|
3744
|
+
survivors and an unconfirmed owned stop fail the run. Producer cleanup legs assert
|
|
3745
|
+
that the native group they started stopped, using their original receipt evidence;
|
|
3746
|
+
they retain that pass or fail independently of harness lifetime cleanup. Native
|
|
3747
|
+
lifetime cleanup remains unproven in T1 and is reported without gating eligibility.
|
|
3748
|
+
A passing receipt with eligible policy and confirmed owned stop can be eligible
|
|
3749
|
+
while lifetime cleanup is unproven, provided no survivor was detected. The private
|
|
3750
|
+
workspace is kept until runner destruction; its location is reported only on stderr. A portable
|
|
3751
|
+
process supervisor belongs to a separate follow-up. Disposable runner lifetime is
|
|
3752
|
+
the containment boundary, not fresh HOME or process-group emptiness.
|
|
3753
|
+
|
|
3754
|
+
The output directory is held open before installation. Exclusive, no-follow
|
|
3755
|
+
writes are relative to that handle, so replacing an ancestor cannot redirect the
|
|
3756
|
+
receipt. The receipt excludes raw native stdout/stderr and private prefix paths.
|
|
3757
|
+
No PR is created by T1. The [T1b producer report](verification/2026-11-07-compat-receipt-producers-1248.md) maps the promoted Kimi and Qwen modules to their original receipts. Publisher integration is T2. The [Jcode reconstruction](verification/2026-11-07-jcode-receipt-reconstruction-1248.md) retains its failed native control legs and unverified Mac qualification.
|
|
3758
|
+
|
|
3553
3759
|
|
|
3554
3760
|
## Upgrade and crash recovery
|
|
3555
3761
|
|
|
@@ -3625,7 +3831,7 @@ or the plugin is older than the daemon it installed (#1179). It prints nothing w
|
|
|
3625
3831
|
| Runtime | Control protocol window | Legacy status field |
|
|
3626
3832
|
| --- | --- | --- |
|
|
3627
3833
|
| 0.12.20 through 0.25.0 | 16 only | `protocol: 16` |
|
|
3628
|
-
| 0.26.0 through 0.
|
|
3834
|
+
| 0.26.0 through 0.35.0 | 16 through 17 | `protocol: 16`, `protocolMin: 16`, `protocolMax: 17` |
|
|
3629
3835
|
|
|
3630
3836
|
New clients choose the highest common protocol. The protocol window remains 16
|
|
3631
3837
|
through 17, so the published protocol-16 client and channel plugin remain usable; unrelated feature
|
|
@@ -3633,7 +3839,10 @@ capabilities still require their own labels. A disjoint window refuses with 4426
|
|
|
3633
3839
|
The compatibility-floor `protocol` field remains readable by old clients.
|
|
3634
3840
|
|
|
3635
3841
|
Release N-1 is counted in minor versions, separately from this protocol window
|
|
3636
|
-
(#1164, family contract entelecheia/ai-workspace#70). For 0.
|
|
3842
|
+
(#1164, family contract entelecheia/ai-workspace#70). For 0.35.x, N-1 is 0.34.1,
|
|
3843
|
+
the latest published patch of 0.34.x (exact `@staix/agent-mem` 0.22.1, control
|
|
3844
|
+
protocol 17 with descriptor floor 16). Every patch on 0.35.x keeps that release
|
|
3845
|
+
baseline. For 0.34.x, N-1 is 0.33.0,
|
|
3637
3846
|
the latest published patch of 0.33.x (exact `@staix/agent-mem` 0.22.1, control
|
|
3638
3847
|
protocol 17 with descriptor floor 16). Every patch on 0.34.x keeps that release
|
|
3639
3848
|
baseline. For 0.33.x, N-1 is 0.32.0,
|
|
@@ -4395,6 +4604,97 @@ and doctor. Every route without the `hub/` prefix, including named legacy routes
|
|
|
4395
4604
|
and `sy/` selections, uses the fixed alias with one warning. Loading or reloading
|
|
4396
4605
|
never rewrites the operator's routing files.
|
|
4397
4606
|
|
|
4607
|
+
#### Optional adec decision route (#554)
|
|
4608
|
+
|
|
4609
|
+
The optional `decision` route calls a separately managed, loopback-only
|
|
4610
|
+
`adec serve` using the [agent-decide route contract](https://github.com/STAIxBWLB/agent-decide/issues/4).
|
|
4611
|
+
The hub never starts or configures that service, reads its credentials, or calls
|
|
4612
|
+
its model directly. This backend is selected explicitly:
|
|
4613
|
+
|
|
4614
|
+
```toml
|
|
4615
|
+
[hub_routes."hub/decision"]
|
|
4616
|
+
type = "decision"
|
|
4617
|
+
decision_backend = "adec"
|
|
4618
|
+
decision_mode = "shadow"
|
|
4619
|
+
policy_id = "ahub.chat"
|
|
4620
|
+
adec_endpoint = "http://127.0.0.1:8740/v1/route"
|
|
4621
|
+
decision_timeout_ms = 8000
|
|
4622
|
+
efficient = "fast"
|
|
4623
|
+
capable = "coding"
|
|
4624
|
+
candidates = [
|
|
4625
|
+
{ alias = "fast", efforts = ["low", "medium"] },
|
|
4626
|
+
{ alias = "coding", efforts = ["high"] },
|
|
4627
|
+
]
|
|
4628
|
+
```
|
|
4629
|
+
|
|
4630
|
+
Select it by editing the existing `[local] route` or class `route` to
|
|
4631
|
+
`"hub/decision"`. Do not append a duplicate `[local]` table. Ordinary routes,
|
|
4632
|
+
class `fixed_model` selections and a person's explicit model override retain
|
|
4633
|
+
their existing behavior; an explicit model bypasses this route.
|
|
4634
|
+
|
|
4635
|
+
Omitting `decision_mode` means `off`: no decision request or evidence is built.
|
|
4636
|
+
This delivery supports `shadow` only. It records the proposed alias/effort,
|
|
4637
|
+
margin, latency and decider while keeping the exact existing stage heuristic
|
|
4638
|
+
model, effort and conversation. `enforce` is explicitly refused at config load:
|
|
4639
|
+
`decision_mode enforce is not available yet; use shadow; tracked in #554`.
|
|
4640
|
+
There is no dormant application path or gateway effort plumbing. No route is
|
|
4641
|
+
enabled by default or deployed by this feature.
|
|
4642
|
+
|
|
4643
|
+
The configured alias/effort list has at most 26 pairs. Aliases narrow the adec
|
|
4644
|
+
policy; efforts are an additional hub-side response allowlist and are not sent
|
|
4645
|
+
as a policy override. Align the lists with the service policy: an unconfigured
|
|
4646
|
+
effort is refused as `outside_options`, keeping the heuristic. The request
|
|
4647
|
+
cannot add a policy candidate. The service assembles its question and
|
|
4648
|
+
owns its hard rules, margin threshold, in-memory pins and fallback. A valid
|
|
4649
|
+
`fallbackApplied` pair is recorded as the service's proposed fallback even when
|
|
4650
|
+
`abstain` is true. Every proposal, failure and `no_candidate` keeps the hub
|
|
4651
|
+
heuristic unchanged. An HTTP 400 is a caller/configuration
|
|
4652
|
+
error; inspect the policy id and allowed pairs. Transport errors, timeout,
|
|
4653
|
+
malformed responses and an out-of-list pair also keep the hub heuristic, with a
|
|
4654
|
+
closed reason in the route event. A failed service is not asked again in the
|
|
4655
|
+
same user turn. Operational diagnostics contain a closed cause and repair step,
|
|
4656
|
+
and are emitted once per state/configuration change; a successful reply resets
|
|
4657
|
+
the diagnostic so a later recurrence is visible. Per-call route records remain
|
|
4658
|
+
available for outcome correlation. The default total timeout is 8 seconds (configurable from 1 to
|
|
4659
|
+
30000 ms), covering headers and the full bounded response. Redirects, ambient
|
|
4660
|
+
proxies, credentials and browser headers are not used. Endpoint URLs accept only
|
|
4661
|
+
HTTP numeric loopback with `/v1/route`, without userinfo, query or fragment.
|
|
4662
|
+
|
|
4663
|
+
Each eligible tool round carries the same opaque, route/session/user-turn-bound
|
|
4664
|
+
`turnId`. adec therefore reuses its pin while rechecking current hard rules.
|
|
4665
|
+
The hub does not send a proposal as `current`: no pair is applied in shadow,
|
|
4666
|
+
and the native/default effort is unknown. Explicit model selections bypass the
|
|
4667
|
+
service.
|
|
4668
|
+
Changing a service, provider, model, version or policy threshold requires a new
|
|
4669
|
+
shadow period. The hub does not recalibrate a remote policy. The optional decider `version` is recorded when configured on the service;
|
|
4670
|
+
otherwise it stays unknown and is not inferred from the model id. Moving
|
|
4671
|
+
`latest` version aliases are refused.
|
|
4672
|
+
|
|
4673
|
+
Evidence is a bounded data projection, never the forwarded conversation: a
|
|
4674
|
+
capped latest-user task fragment, the last assistant/tool tails, screened tool
|
|
4675
|
+
names and numeric stage dimensions. Whole selected sources pass the current
|
|
4676
|
+
public-view pattern/private-path/secret checks before UTF-8/JSON byte caps.
|
|
4677
|
+
Tool arguments, system/developer instructions and older history are not sent.
|
|
4678
|
+
The total evidence cap is 8 KiB; candidate and response payloads have finite
|
|
4679
|
+
bounds too. Evidence is labelled untrusted data, not instructions; injection
|
|
4680
|
+
resistance is not claimed. Review-observer-excluded and remote turns skip adec.
|
|
4681
|
+
A PII/private turn needs positive `onCampus()` before any evidence build or
|
|
4682
|
+
service call. Even on campus, its evidence is dimensions only, its context size
|
|
4683
|
+
is redacted to 0, and its separate `pii`/`private` flags reach adec so the service
|
|
4684
|
+
can enforce on-prem candidates/decider rules. The ordinary gateway campus and
|
|
4685
|
+
execution-budget checks still apply. Current board/turn privacy and observer
|
|
4686
|
+
facts are checked again across admission, campus and service awaits. A changed
|
|
4687
|
+
or unavailable authority refuses the stale turn instead of turning into a
|
|
4688
|
+
service-error fallback; inspect current task policy and retry. A returned proposal is checked again before telemetry. The original gateway
|
|
4689
|
+
execution path and its privacy/budget checks are unchanged. Source text, tool arguments, credentials
|
|
4690
|
+
and server error prose never enter route events.
|
|
4691
|
+
|
|
4692
|
+
This delivery is the adec consumer slice of #554. The direct System One backend,
|
|
4693
|
+
enforcement application, optional stage classifier and manual offline triage
|
|
4694
|
+
evaluation remain separate unimplemented legs. Offline fake-service tests establish protocol and shadow
|
|
4695
|
+
behavior; no routing gain, native service/model run or production rollout is
|
|
4696
|
+
claimed.
|
|
4697
|
+
|
|
4398
4698
|
Migrate the retired settings as follows:
|
|
4399
4699
|
|
|
4400
4700
|
| Retired setting or route | In-process replacement |
|
|
@@ -4574,18 +4874,18 @@ durable-delivery retries remain the journal's responsibility.
|
|
|
4574
4874
|
|
|
4575
4875
|
## Documentation source verification
|
|
4576
4876
|
|
|
4577
|
-
`docs/verified.json` maps README,
|
|
4578
|
-
|
|
4877
|
+
`docs/verified.json` maps README, every page directly under `docs/` and
|
|
4878
|
+
`docs/addons/`, and every agent note to a full source commit and explicit covered paths.
|
|
4579
4879
|
A stamp records a human check of the cited paths, symbols, numeric limits and
|
|
4580
4880
|
operational commands. It does not certify live deployment or prove prose
|
|
4581
4881
|
correctness automatically. Specs, changelogs and the smoke ledger retain their
|
|
4582
|
-
own dated evidence and are outside this manifest.
|
|
4882
|
+
own dated evidence and are outside this manifest; so does the retired GSD analysis.
|
|
4583
4883
|
|
|
4584
4884
|
`node scripts/check-docs.mjs` also runs in `scripts/check.sh`. Missing manifest
|
|
4585
4885
|
coverage, unresolved or nonancestor commits, removed source paths and a README
|
|
4586
4886
|
status version different from `package.json` fail the gate. Source commits since
|
|
4587
4887
|
a stamp and uncommitted covered changes produce sorted stale notices without
|
|
4588
|
-
failing it. Counts are commits touching any covered path, rather than file or
|
|
4888
|
+
failing it; CI's `decision` job repeats them as warnings on every pull request. Counts are commits touching any covered path, rather than file or
|
|
4589
4889
|
line counts; an unrelated commit leaves the document fresh. Git history must
|
|
4590
4890
|
include the stamped ancestors (CI checks out full history).
|
|
4591
4891
|
|
|
@@ -4653,10 +4953,11 @@ makes `scripts/check.sh` run slice `i` of the full suite through `bun test --sha
|
|
|
4653
4953
|
every test file in exactly one shard and balances them by the recorded per-file times; shard 1 also runs the docs check, typecheck, role check, bundle freshness and
|
|
4654
4954
|
package contents, so each of those runs once per gate, and the others install and test. Each shard runs under the same 1500 s backstop as Linux inside a 25-minute job
|
|
4655
4955
|
limit, and its last line is `check: OK (shard i/n)`. The required check `check (macos-latest)` is an aggregator job that passes only when every shard passed (or an
|
|
4656
|
-
identical-tree full proof was reused), so branch protection and the reuse proof read the same names as before. `AHUB_CHECK_SHARD` is the full suite only: it cannot be
|
|
4956
|
+
identical-tree full proof was reused), so branch protection and the reuse proof read the same names as before. A stacked pull request (base not `main`) runs no macOS shard, and its `check (macos-latest)` fails with "macOS shards deferred", naming the base (#1307): GitHub allows 5 macOS jobs at once on this account, and such a PR is rebased and rerun once it targets `main`. A PR retargeted to `main` without a new commit gets its macOS run by a push, or by `gh pr close <n> && gh pr reopen <n>`; `gh run rerun` replays the old base and defers again. `AHUB_CHECK_SHARD` is the full suite only: it cannot be
|
|
4657
4957
|
combined with `--changed`. A shard execs the system git once before its tests (`AHUB_CHECK_WARM_GIT`, default `/usr/bin/git`; a failure of it is ignored), because the first execs of `/usr/bin/git` on a fresh hosted macOS runner outlast the 1000 ms some tests give it. `scripts/test-timings.json` is advice for balance, never a list of tests: a file missing from it still runs (Bun gives it the median time).
|
|
4658
4958
|
Regenerate it from a green macOS leg when the shards drift apart: `gh api --allow-escape-sequences repos/<owner>/<repo>/actions/jobs/<macOS shard job id>/logs`
|
|
4659
|
-
for each shard, or from one unsharded leg's log, then `bun scripts/make-test-timings.ts <log
|
|
4959
|
+
for each shard, or from one unsharded leg's log, then `bun scripts/make-test-timings.ts <log>...`, or `bun scripts/refresh-test-timings.ts` for the newest green run (#1257).
|
|
4960
|
+
A red CI job gets one rerun of its failed jobs on the same head, then an investigation; the weekly flake ledger issue and the rerun policy are in `docs/agent-notes/tests.md` (#1257).
|
|
4660
4961
|
The `closing-refs` workflow fails a PR whose title, body or commit messages would make
|
|
4661
4962
|
GitHub close an issue the text only mentions (`Refs #N`, a negated or qualified keyword);
|
|
4662
4963
|
an issue linked only in the sidebar passes (#760).
|
|
@@ -5001,11 +5302,11 @@ Native policy is unmanaged and has NO hub sandbox; no permission_modes.jcode or
|
|
|
5001
5302
|
|
|
5002
5303
|
## Optional Antigravity (agy) peer
|
|
5003
5304
|
|
|
5004
|
-
Antigravity is optional and off roster by default. Use `ahub roster add agy`, then run `ahub agy` in a terminal: it runs the Antigravity CLI as a fresh pull-only TUI in that terminal. It accepts the 1.4.x line: 1.4.2, 1.4.7
|
|
5305
|
+
Antigravity is optional and off roster by default. Use `ahub roster add agy`, then run `ahub agy` in a terminal: it runs the Antigravity CLI as a fresh pull-only TUI in that terminal. It accepts the 1.4.x line plus exact 1.5.3: 1.4.2, 1.4.7, 1.4.12 and 1.5.3 are the verified versions ([1.4.7 receipt](verification/2026-10-26-agy-1.4.7.md), [1.4.12 launcher nonce receipt](verification/2026-11-03-agy-1.4.12-launcher-nonce.md), [1.5.3 account-free receipt](verification/2026-11-08-agy-1.5.3.md)), any other 1.4.x launches with a stderr warning (agy updates itself, so the launcher sets `AGY_CLI_DISABLE_AUTO_UPDATE=1` for its version probe and the TUI it starts, #1140, #1286), and other versions are refused (#589) unless the person trusts that exact version with `ahub agents trust agy <version>` (#691). The running hub must advertise `native_hook_launch`; an older hub refuses before any write with an upgrade-or-restart remedy. Only the person's launcher starts it: conductor starts are refused, there is no controlled restore or resume, and a declared agy extra instance is refused when the config loads (#625). Headless/print, resume (`--conversation`, `--continue`, `--new`), `--mode`, `--dangerously-skip-permissions` and `--unattended` are refused until their native mapping is verified; `--print-command` previews without writing.
|
|
5005
5306
|
|
|
5006
5307
|
The launcher writes exactly `plugin.json`, `mcp_config.json` and `hooks.json` in `.agents/plugins/agent-hub/`, refusing linked or foreign entries before any write, and removes only its own matching files when the TUI ends. It never writes project-level `.agents/hooks.json` or the person's `~/.gemini` settings. Run `ahub init` afterwards to ignore the untracked plugin directory; a tracked plugin is written with a warning. The native model sees the hub tools under the server name `agent-hub_agent-hub`.
|
|
5007
5308
|
|
|
5008
|
-
Like Kimi's TUI, agy is pull-only: it reads `hub_inbox` and shares results with `hub_send`, messages do not interrupt it, and automatic routing never picks it. Its roles are capped at implementer and verifier; a plan or review assignment and PII work are refused. Native permissions are unmanaged, with no hub sandbox, hub permission mode, quota source or session resume. Plugin hooks bound to that launch carry the hub's turn facts and report each completed native turn. A native read is recorded as a peer `Read` fact: `view_file` (`AbsolutePath`) in 1.4.2 and `read_file` (`Path`) in 1.4.3; a `StartLine`/`EndLine` range counts as a partial read, never a whole-file view (#555). The live TUI/account leg is unverified ([T0 receipt](verification/2026-10-19-agy-p1-t0.md)). The 1.4.3 T0 re-run keeps 1.4.3 unverified: its `call_mcp_tool` schema and native tool names changed, and the TUI attaches the hub tools only from the second model turn ([1.4.3 receipt](verification/2026-10-21-agy-1.4.3-t0.md), #607).
|
|
5309
|
+
Like Kimi's TUI, agy is pull-only: it reads `hub_inbox` and shares results with `hub_send`, messages do not interrupt it, and automatic routing never picks it. Its roles are capped at implementer and verifier; a plan or review assignment and PII work are refused. Native permissions are unmanaged, with no hub sandbox, hub permission mode, quota source or session resume. Plugin hooks bound to that launch carry the hub's turn facts and report each completed native turn. When messages wait at a model boundary (`SessionStart`, `PreInvocation`), the hook adds one count-only line asking it to call `hub_inbox`, never a body or sender (#1280). A native read is recorded as a peer `Read` fact: `view_file` (`AbsolutePath`) in 1.4.2 and `read_file` (`Path`) in 1.4.3; a `StartLine`/`EndLine` range counts as a partial read, never a whole-file view (#555). The live TUI/account leg is unverified ([T0 receipt](verification/2026-10-19-agy-p1-t0.md)). The 1.4.3 T0 re-run keeps 1.4.3 unverified: its `call_mcp_tool` schema and native tool names changed, and the TUI attaches the hub tools only from the second model turn ([1.4.3 receipt](verification/2026-10-21-agy-1.4.3-t0.md), #607).
|
|
5009
5310
|
|
|
5010
5311
|
## Configured ACP adapters (#451 A3)
|
|
5011
5312
|
|
|
@@ -5616,7 +5917,7 @@ A headless Claude implementer (#525-4) is declared separately:
|
|
|
5616
5917
|
"claude-impl": { "kind": "claude", "roles": ["implementer"], "start_mode": "headless", "worktree": ".worktrees/claude-impl", "permission_mode": "ask" }
|
|
5617
5918
|
```
|
|
5618
5919
|
|
|
5619
|
-
A headless Claude implementer may name its model (#844): `"model": "claude-sonnet-5-5"` on its declaration passes `--model <value>` on every native turn, resumed ones included. It is one bounded word (letters, digits and `._:/@+-`, up to 128 bytes, no spaces and no leading dash) and is accepted only on a headless implementer, only from the untracked `config.local.json`. A tracked-file declaration is ignored with a reason, and the key is tier 3: the dashboard and a settings session cannot read or change it, only the console or your editor. Unset, the argv is unchanged and Claude uses its own default. `ahub status` shows the model on the instance row as `model source`. Declarations are captured once when the hub daemon starts, so a changed or newly added `model` takes effect after a hub daemon restart (`ahub restart`); restarting only the instance keeps the old model.
|
|
5920
|
+
A headless Claude implementer may name its model (#844): `"model": "claude-sonnet-5-5"` on its declaration passes `--model <value>` on every native turn, resumed ones included. It is one bounded word (letters, digits and `._:/@+-`, up to 128 bytes, no spaces and no leading dash) and is accepted only on a headless implementer, only from the untracked `config.local.json`. A tracked-file declaration is ignored with a reason, and the key is tier 3: the dashboard and a settings session cannot read or change it, only the console or your editor. Unset, the argv is unchanged and Claude uses its own default. `ahub status` shows the model on the instance row as `model source`. Declarations are captured once when the hub daemon starts, so a changed or newly added `model` takes effect after a hub daemon restart (`ahub restart`); restarting only the instance keeps the old model. For a person-owned next-turn override without changing that configuration path, use [live peer model overrides](#live-peer-model-overrides-1317).
|
|
5620
5921
|
|
|
5621
5922
|
Create and register the attached-branch worktree first; the hub never creates it implicitly. `ahub claude --as claude-impl` asks the hub to start the instance and returns. Idle holds no native child. Task deliveries use a persisted UUID per task: first `--session-id`, later `--resume`. Unscoped chat reuses a session only when exactly one task is in progress for the instance; otherwise it is ephemeral. Positive missing-transcript evidence starts fresh with a notice; unknown read evidence retains the id. Reset includes the per-peer session map. A child inbox read refuses a queued batch attributed to another task and leaves it queued for that task's own session.
|
|
5622
5923
|
|
|
@@ -5770,7 +6071,7 @@ Native launcher connections retry transport timeouts/unclean closes with bounded
|
|
|
5770
6071
|
|
|
5771
6072
|
## amem runtime (agent-mem#13 P4)
|
|
5772
6073
|
|
|
5773
|
-
The hub exact-pins @staix/agent-mem 0.
|
|
6074
|
+
The hub exact-pins @staix/agent-mem <!-- facts:agent-mem-pin -->0.23.1<!-- /facts:agent-mem-pin --> for recall, curated evidence and local deterministic capture. No runtime call reaches a claude-mem worker; `memory.worker_url` is ignored. The person's `ahub memory import claude-mem` remains explicit and off by default. Existing profile, alias, PII and private-turn fences still apply. `ask --remember` and context checkpoints propose machine-local candidates, never automatic curated evidence. See [memory integration](memory.md#in-process-recall-and-capture-agent-mem13-p4) for changed behavior and bounded-view ceilings.
|
|
5774
6075
|
|
|
5775
6076
|
## Person-run backlog legs (#1176)
|
|
5776
6077
|
|
|
@@ -6344,7 +6645,7 @@ ahub worktrees tidy --confirm <fingerprint> # the person's own terminal: re-r
|
|
|
6344
6645
|
|
|
6345
6646
|
## Results: what a run you started left behind (#1054)
|
|
6346
6647
|
|
|
6347
|
-
A run you started (a message you sent to a peer, from the console, `ahub say` or acon) settles into one **result** when the adapter's own signal says it ended and nothing else is pending: no queued continuation, open permission or question, owned child, running check or held delivery. Peers whose adapter declares no settle signal (Kimi in its own TUI
|
|
6648
|
+
A run you started (a message you sent to a peer, from the console, `ahub say` or acon) settles into one **result** when the adapter's own signal says it ended and nothing else is pending: no queued continuation, open permission or question, owned child, running check or held delivery. Peers whose adapter declares no settle signal (agy, person-typed Codex turns) leave none; Kimi in its own TUI leaves one only when started with `ahub kimi` on the verified Kimi 2.5.2 (see [Kimi in its own TUI](#kimi-in-its-own-tui)). Outcomes are `done`, `failed`, `limit` and `interrupted` (the hub restarted mid-run); an explicit stop by you and a budget pause leave no result. A result is **unread** until you mark it read; nothing a snapshot, `ahub status` or `ahub results` reads ever marks one.
|
|
6348
6649
|
|
|
6349
6650
|
- `ahub results [--unread]` lists them, newest first, unread ones marked `*`: id, `<peer>: <outcome word>` (a private result is `a private result`), when it settled and how long it ran. It prints no prompt and no reply.
|
|
6350
6651
|
- `ahub results --read <id>` marks one read (it must exist and be unread). `--read-all` marks every unread result of the project. `--unread-last` lights the most recent read one again by deleting its receipt.
|
|
@@ -6405,13 +6706,13 @@ Corrupt or unreadable provenance stays unknown and held. The status next step di
|
|
|
6405
6706
|
|
|
6406
6707
|
A ready memory profile does not prove a successful sync. Read the separate automatic-sync result and timestamp in `ahub status` or Memory. It resets to not run after daemon restart; it is not a machine-global record of manual CLI attempts. Missing remote configuration is the neutral `not-configured` state; an interrupted/stopped attempt is neutral `stopped`. Both keep their safe next step and produce no failure log under `quietSyncError`.
|
|
6407
6708
|
|
|
6408
|
-
For policy-declined rows, a person runs `ahub memory declined --json` to inspect IDs and safe rule categories, never note text. The pinned agent-mem 0.
|
|
6709
|
+
For policy-declined rows, a person runs `ahub memory declined --json` to inspect IDs and safe rule categories, never note text. The pinned agent-mem 0.23.1 public `inspectSyncPolicy` API bounds physical outbound inspection for shared-v1 and generation profiles. A complete result supplies the declined IDs and rules; `complete:false` means the scan is unavailable, stale or over its diagnostic bound, not zero declined rows. The command stays read-only and rechecks its profile binding. No migration or policy edit is performed automatically.
|
|
6409
6710
|
|
|
6410
|
-
The hub projects verified withheld/exported counts when a trusted SDK sync returns a successful placement result. That projection is covered by an injected-result fixture, not an activated-store sync. Agent-mem
|
|
6711
|
+
The hub projects verified withheld/exported counts when a trusted SDK sync returns a successful placement result. That projection is covered by an injected-result fixture, not an activated-store sync. Agent-mem requires a fresh `placementAttestation` even for an already active v3 store; since 0.35.0 the daemon builds one with the package's own `createPlacementAttestation` on every sync pass and supplies no writer facts of its own, so no attestation is fabricated. A refused attestation is the closed cause `writer` in status, the dashboard and the log: its category, its cause class (`missing`, `changed`, `unavailable`) and the next step (repair the amem install and its host pin, then a person runs `amem migrate --sync-placement --dry-run`). Activation remains a person-run action. A nonzero withheld count in a successful result is not a transport failure and does not mean those rows were deleted, rewritten or published. Inspect the IDs and rules before deliberately changing any source or approved policy; a forget operation does not remove its original text from physical history.
|
|
6411
6712
|
|
|
6412
|
-
A legacy store without active per-row placement still blocks a sync containing declined rows. Status names inactive placement and the person-only `amem migrate --sync-placement --dry-run` preview, which requires every local writer installation through repeatable `--writer-root` flags. It
|
|
6713
|
+
A legacy store without active per-row placement still blocks a sync containing declined rows. Status names inactive placement and the person-only `amem migrate --sync-placement --dry-run` preview, which requires every local writer installation through repeatable `--writer-root` flags. It keeps `ahub memory declined` as the safe inspection step. The native CLI supports activation from 0.22.0; the pinned core is 0.23.1. See the [activation preview and prerequisites](memory.md#automatic-sync-health-1173) before any separately authorized apply. Preview writes nothing, and activation does not migrate layouts, change policy or automatically raise a format floor. The hub does not invoke it or fabricate its proof.
|
|
6413
6714
|
|
|
6414
|
-
The bounded diagnostic addresses #1173 AC4; AC5 has result projection
|
|
6715
|
+
The bounded diagnostic addresses #1173 AC4; AC5 has result projection and the host attestation. Whether an activated store syncs on a person's machine is not established by the isolated fixtures.
|
|
6415
6716
|
|
|
6416
6717
|
For a transport or unknown failure, run `ahub memory sync` as a person to see the local diagnostic. Logs keep only the cause class and known declined count, once per unchanged failure episode. Complete declined-ID sets can distinguish a changed failure without placing IDs or bodies in the log; incomplete inspection keeps the set unknown. Existing write-time screening and profile/privacy fences remain. SDK adoption and isolated fixtures do not prove live rollout or a successful sync of the person's memory home.
|
|
6417
6718
|
|
|
@@ -6444,3 +6745,217 @@ Upgrade the broker, then every room member to a codec-capable release, then reco
|
|
|
6444
6745
|
`ahub status` distinguishes local room storage opening from a failed broker
|
|
6445
6746
|
connection; direct `ahub room status` failures expose only closed cause/action
|
|
6446
6747
|
metadata. A healthy online link needs no broker repair advice.
|
|
6748
|
+
|
|
6749
|
+
## Optional Orca companion contract (#1198 O0)
|
|
6750
|
+
|
|
6751
|
+
The [versioned O0 contract](../integrations/orca/host-contract-v1.md) and its
|
|
6752
|
+
[capability matrix](../integrations/orca/host-contract-v1.json) describe the
|
|
6753
|
+
installed Orca 1.4.252 declarations, pinned primary references and reusable
|
|
6754
|
+
fake-host/CLI fixtures. O0 installs no plugin and changes no ahub runtime.
|
|
6755
|
+
Worker and frame APIs differ: workspace inventory/navigation are worker-only;
|
|
6756
|
+
focused context lacks the exact workspace id, execution host and real root
|
|
6757
|
+
needed to select a project. Names and branches are never selection authority.
|
|
6758
|
+
|
|
6759
|
+
Terminal focus remains unsupported until a plugin terminal id can be bound to a
|
|
6760
|
+
current same-host CLI handle. Workspace navigation and manual `ahub console` /
|
|
6761
|
+
`ahub ui` commands remain available independently of a companion. No remote
|
|
6762
|
+
loopback URL is opened locally. Native local, remote, Windows and mobile results
|
|
6763
|
+
are recorded separately; declarations and fake results do not qualify them.
|
|
6764
|
+
The three baseline journeys count procedure actions only, with observed native
|
|
6765
|
+
counts still unknown. O1 must record actual open/disable/standalone UI proof.
|
|
6766
|
+
|
|
6767
|
+
### Optional Orca companion: chooser and entry points (#1198 O1)
|
|
6768
|
+
|
|
6769
|
+
[`integrations/orca/`](../integrations/orca/README.md) holds the optional companion: a manifest, a
|
|
6770
|
+
trusted worker and a sidebar panel. It is not in the npm package, no ahub source refers to it, and ahub and
|
|
6771
|
+
Orca keep all their own functionality without it. It lists Orca's workspaces, you select one by its exact
|
|
6772
|
+
id (a name or branch never selects), and it opens an existing screen: `ahub ui` run as a short-lived child
|
|
6773
|
+
with the folder as its working directory only, or a terminal created in the workspace running `ahub console`
|
|
6774
|
+
or `acon ui`. A selection binds the id, host id, kind and the folder's real path on this Mac and is
|
|
6775
|
+
re-checked against a complete inventory before every effect; a duplicate, missing, truncated or changed
|
|
6776
|
+
identity, or a host not declared to be this Mac, refuses visibly and runs nothing. It never passes `--json`
|
|
6777
|
+
to `ahub ui`, never approves, assigns, completes, retries, stops or upgrades anything, and keeps no CLI
|
|
6778
|
+
output, one-time link or task text in plugin state or logs.
|
|
6779
|
+
|
|
6780
|
+
Install is explicit and in an isolated Orca profile first (`orca plugin validate`, `orca plugin dev load`
|
|
6781
|
+
with the fingerprint Orca prints); remove it with `orca plugin disable` and `orca plugin dev unload`. The
|
|
6782
|
+
fake-host checks are `test/orca-companion-entry.test.ts` and `test/orca-companion-independence.test.ts`.
|
|
6783
|
+
A **Show status** button (O2) reads the selected project's public status on a click only: version, tasks by
|
|
6784
|
+
state, and peer state with queue length, copied from `ahub status --json` through a closed allowlist so no
|
|
6785
|
+
free-text field (task title, a peer's current line, a notice, a path) is read. Offline, unavailable version,
|
|
6786
|
+
partial, stale and unknown stay distinct states; there is no poller, no transcript read and no terminal read.
|
|
6787
|
+
There is **no terminal focus**: O0 found no proof that a plugin terminal id names an `orca terminal switch`
|
|
6788
|
+
handle, so the companion never calls it and never replaces a terminal.
|
|
6789
|
+
|
|
6790
|
+
**Platforms (O3).** [`support-matrix.json`](../integrations/orca/support-matrix.json) records one verdict per
|
|
6791
|
+
combination and a test enforces that `supported` needs a receipt that no longer says NOT RUN. Today none is
|
|
6792
|
+
supported: macOS local is fixture-only, and remote, Windows, browser or mobile and Linux are unsupported, each
|
|
6793
|
+
with a person-run receipt template under `integrations/orca/receipts/`. A remote workspace is refused before
|
|
6794
|
+
anything runs and shows the existing remote console command to run on that host; a remote loopback link is never
|
|
6795
|
+
opened locally. On Windows every workspace is refused (`unsupported_platform`). Where a client has no external
|
|
6796
|
+
navigation no link is held. Mobile availability is not inferred from SSH reachability or from Orca's mobile
|
|
6797
|
+
pairing option.
|
|
6798
|
+
|
|
6799
|
+
**The native open and disable receipt is a person-run leg that has not been run**
|
|
6800
|
+
([`native-receipt.md`](../integrations/orca/native-receipt.md)): the action counts in the companion's README
|
|
6801
|
+
are procedure counts, remote, Windows and mobile stay unqualified (O3), and there is no focus-existing-console
|
|
6802
|
+
action.
|
|
6803
|
+
|
|
6804
|
+
## Herdr companion host contract (#1199 H0)
|
|
6805
|
+
|
|
6806
|
+
[`integrations/herdr/host-contract-v1.md`](../integrations/herdr/host-contract-v1.md) freezes what an optional Herdr mod may
|
|
6807
|
+
rely on, taken from the installed app's own declarations (Herdr 0.1.13, herdr-core 0.1.18, hashes recorded), and records
|
|
6808
|
+
what was not observed. It changes no ahub runtime and installs nothing. `exec` is bounded (30 s, 8 MiB) and used for
|
|
6809
|
+
reads only. The pane's machine and cwd are a navigation hint: the project root comes from `ahub projects --json` read on
|
|
6810
|
+
that same machine, and a remote cwd is never resolved on this Mac. Herdr has no install or disable command, so a mod is
|
|
6811
|
+
a folder the person adds and removes, and what removal does to a shown copy is for the H1 native receipt. Existing
|
|
6812
|
+
terminal focus is unbuilt until a Herdr terminal can be mapped to an ahub console. The three baseline journeys are
|
|
6813
|
+
procedure counts that have not been run in a native window.
|
|
6814
|
+
|
|
6815
|
+
### Who owns a pull-only peer (#1310)
|
|
6816
|
+
|
|
6817
|
+
`ahub status` (and `--json`) names the current owner of an attached channel peer, beside its standby rows: `<peer> owner: pid <n>; attached <age>; native session <id>`. The pid is what the owner's plugin reported at hello (`pid unknown` when it reported none or an unusable one). `attached` is when the attach finished, not when the hello arrived. The native session reads `unverified` until the hub has verified one through the native-facts path (today agy), and an id that is not a short plain token is never shown. The owner line is absent while a newer session is still arriving, while the peer is offline, and after a detach, so a claimant is never shown as attached, and a takeover replaces the whole line at once. Use it to see who holds a queued peer before running `ahub peer takeover`. It is display only: it never decides delivery, takeover or permission, and `status.json` on disk does not carry it.
|
|
6818
|
+
|
|
6819
|
+
### Herdr project and machine entry (#1199 H1)
|
|
6820
|
+
|
|
6821
|
+
[`integrations/herdr/`](../integrations/herdr/README.md) is an optional mod: three files the person copies to
|
|
6822
|
+
`mods/ahub` in the Herdr app home, which Herdr reads live and which declares `place: none`, so no layout changes.
|
|
6823
|
+
It lists the focused space's machine and folder and that machine's registered projects, and opens nothing until a
|
|
6824
|
+
row is selected. Open console starts one new tab in the selected space running `ahub --project <id> console`, with the project root
|
|
6825
|
+
as the tab's folder. Before every effect it re-reads the space, the machine and the registrations and runs
|
|
6826
|
+
`ahub status --json` from the project folder, and refuses a changed, duplicate, offline or unready target. The local
|
|
6827
|
+
dashboard runs the existing `ahub ui` and keeps no link or ticket. A remote space gets the console tab or a copyable
|
|
6828
|
+
command, never a dashboard link. Remove it by deleting the folder. It starts, stops and upgrades nothing and is not an
|
|
6829
|
+
ahub dependency. `herdr-app check` accepts it in a scratch home; the native open and disable receipt is a person-run
|
|
6830
|
+
leg that has not been run.
|
|
6831
|
+
|
|
6832
|
+
### Herdr status card and existing-console focus (#1199 H2)
|
|
6833
|
+
|
|
6834
|
+
The Herdr entry also offers three read-only actions. **Status** reads `ahub --project <id> status --json` from the project folder on the
|
|
6835
|
+
selected machine, on a click only, and shows task counts, peer states and queue lengths and the hub version from a closed
|
|
6836
|
+
allowlist, so no task or note text reaches it. Missing CLI, timeout, an exit error, no hub running, oversized or
|
|
6837
|
+
unrecognized output, an old hub, a partial reading and a stale one are distinct states. **Focus console** and **Peek
|
|
6838
|
+
console** (this computer only) accept a terminal only after `hc get` shows it live and running `ahub console` for the
|
|
6839
|
+
selected project, exactly one match, rechecked right before a single `pane.focus` or `terminal.peek`, and a focus is
|
|
6840
|
+
believed only after Herdr's `focused()` shows it. They never start, replace, type into or close a terminal, and
|
|
6841
|
+
Herdr's own working, blocked, done and idle words are shown, never sent to ahub. A console started through a wrapper is
|
|
6842
|
+
not recognized and the person uses Open console. The native focus receipt is a person-run leg that has not been run.
|
|
6843
|
+
|
|
6844
|
+
### Herdr platform support matrix (#1199 H3)
|
|
6845
|
+
|
|
6846
|
+
[`integrations/herdr/support-matrix.json`](../integrations/herdr/support-matrix.json) records one verdict per combination and a
|
|
6847
|
+
test enforces that `supported` needs a receipt that no longer says NOT RUN. Today none is supported: macOS local is
|
|
6848
|
+
fixture-only, and remote, Windows, Linux and browser or mobile are unsupported, each with a person-run receipt template under
|
|
6849
|
+
`integrations/herdr/receipts/`. The remote console workflow is designed (read on that machine, new tab in that machine's space,
|
|
6850
|
+
no dashboard link, no remote focus) and exercised against the fixture only, because no remote machine is configured on the
|
|
6851
|
+
machine it was built on. On Windows every action refuses. Mobile is not inferred from SSH reachability or a machine being ready.
|
|
6852
|
+
[`baseline-comparison.md`](../integrations/herdr/baseline-comparison.md) lays the entry's journeys beside the H0 baseline as
|
|
6853
|
+
procedure counts: the entry costs one more action than the baseline when the pane is already in the right project, and its value
|
|
6854
|
+
is the verified machine and root, not a shorter path.
|
|
6855
|
+
|
|
6856
|
+
## Bounded visual attachments (#1058)
|
|
6857
|
+
|
|
6858
|
+
`hub_visual` lets an ordinary local peer or the local worker annotate public work
|
|
6859
|
+
with a Mermaid diagram, comparison, table or before/after view. It is a separate
|
|
6860
|
+
tool, not extra fields in `hub_send`. Its input is `{payload, task?, to?}` and its
|
|
6861
|
+
receipt is `visual <id>`. `hub_visual_show {id}` explicitly reads a retained public
|
|
6862
|
+
record in this project. Read-only roles may read; publication still requires the
|
|
6863
|
+
ordinary shared-note capability and no-writes admission. Isolated fresh-reviewer
|
|
6864
|
+
MCP remains limited to `hub_review` and `hub_task_show`.
|
|
6865
|
+
|
|
6866
|
+
The stored payload is the exact acon `VisualPayload` shape. acon owns `ui.visual`,
|
|
6867
|
+
its sandboxed Mermaid renderer, table kit and asset route; the hub imports types
|
|
6868
|
+
only. The standalone dashboard shows a readable title and text/source. Stream
|
|
6869
|
+
stubs and task details load a visual on demand. A missing/older acon visual kit
|
|
6870
|
+
keeps the fallback rather than loading another renderer into the hub.
|
|
6871
|
+
|
|
6872
|
+
```json
|
|
6873
|
+
{"payload":{"kind":"mermaid","title":"Review flow","source":"flowchart TD\nPlan --> Implement --> Review"}}
|
|
6874
|
+
```
|
|
6875
|
+
|
|
6876
|
+
The four kinds are `mermaid` (`source`, optional `title`), `comparison` (2-6
|
|
6877
|
+
`options`, optional `title`), `table` (`columns`, `rows`, optional `caption`) and
|
|
6878
|
+
`beforeAfter` (`before`, `after`, optional `caption`). Each comparison option has a
|
|
6879
|
+
title, optional summary, up to 10 pros and 10 cons, and optional `recommended`.
|
|
6880
|
+
Tables allow at most 500 rows and 12 columns. Column fields are `key`, `label`,
|
|
6881
|
+
optional `align: start|end` and `format: text|number|percent`; percent values use
|
|
6882
|
+
percent units as acon does. Cells are strings or finite numbers.
|
|
6883
|
+
|
|
6884
|
+
Mermaid is self-contained source without a Markdown fence, at most 20 KiB UTF-8.
|
|
6885
|
+
The first non-comment line starts with a supported diagram keyword. This is only
|
|
6886
|
+
a header check, not parsing proof: acon shows source with a notice when its parser
|
|
6887
|
+
fails or the renderer times out. The hub adds no parser or Mermaid dependency.
|
|
6888
|
+
|
|
6889
|
+
Hub admission also bounds the entire serialized payload to 1 MiB and each text
|
|
6890
|
+
field: title 300 bytes, caption 2000, alt 1000, text side 20 KiB, option summary
|
|
6891
|
+
4000, each pro/con 2000, table cell 4000, column key 128 and file path 4096. These
|
|
6892
|
+
are hub storage/admission ceilings, distinct from acon's payload type. Every text
|
|
6893
|
+
field and record key is screened before sanitization and again afterwards; an
|
|
6894
|
+
unsafe key is refused rather than renamed. Oversized or malformed data is refused
|
|
6895
|
+
with the field and repair step, never silently truncated or partially stored.
|
|
6896
|
+
|
|
6897
|
+
A before/after side is either `{text}` or a project path with alt text:
|
|
6898
|
+
|
|
6899
|
+
```json
|
|
6900
|
+
{"payload":{"kind":"beforeAfter","caption":"Layout change","before":{"path":"artifacts/before.png","alt":"Previous layout"},"after":{"path":"artifacts/after.png","alt":"Updated layout"}}}
|
|
6901
|
+
```
|
|
6902
|
+
|
|
6903
|
+
Paths are relative to the canonical hub project, not an inferred peer worktree.
|
|
6904
|
+
WebP asset display requires acon 0.1.7 or later (agent-console#81). Older 0.1.3/0.1.4 hosts refuse that MIME type; use PNG or JPEG there. The hub adds no transcoder.
|
|
6905
|
+
|
|
6906
|
+
Only a guarded public PNG, JPEG or WebP of at most 8 MiB is accepted; extension
|
|
6907
|
+
and byte signature must agree. SVG, secret/PII paths, hub state, outside paths,
|
|
6908
|
+
links swapped during inspection and two names for the same physical file refuse.
|
|
6909
|
+
The hub replaces paths in the payload with opaque asset ids and records its own
|
|
6910
|
+
hash. A later asset read repeats the current guard and hash checks; a changed or
|
|
6911
|
+
newly private image is refused as changed since posted. Post it again using a
|
|
6912
|
+
current public file. A copied visual id in another project's database does not
|
|
6913
|
+
select that project's asset: the acon provider binds the project and instance,
|
|
6914
|
+
then rechecks metadata/privacy after the guarded read before returning bytes.
|
|
6915
|
+
|
|
6916
|
+
The default audience is the console, with an FYI chat stub. Explicit `to` uses
|
|
6917
|
+
local addressed delivery, including `to: "user"` for the console; an empty list
|
|
6918
|
+
broadcasts to local peers. An explicit
|
|
6919
|
+
remote recipient refuses the whole call, rather than silently dropping that
|
|
6920
|
+
target. The stub carries only `[visual <id>] <kind>: <title or caption>` and
|
|
6921
|
+
`refs.visual`. Peers receive no source, table/comparison body or inline image.
|
|
6922
|
+
This feature adds no visual transport over the cross-network broker.
|
|
6923
|
+
|
|
6924
|
+
Publication is refused in a private turn or on a PII task, including when policy
|
|
6925
|
+
or task privacy changes during an awaited image read. Current privacy also gates
|
|
6926
|
+
show, snapshots and assets after posting. Visual file access combines accepted
|
|
6927
|
+
runtime restrictions with the normally merged on-disk candidate policy. A pending
|
|
6928
|
+
stricter path rule protects new visual access immediately; a pending weaker file
|
|
6929
|
+
cannot remove the accepted restriction. Native sessions retain their existing
|
|
6930
|
+
configuration-adoption boundary. The raw visual tool input/result is
|
|
6931
|
+
excluded from observer capture even when the call is refused; amem/delivery
|
|
6932
|
+
capture retains only the sanitized stub. `events.jsonl` records only id, kind,
|
|
6933
|
+
payload byte count, image count and optional task id, never title/source/path or
|
|
6934
|
+
image bytes. A visual is explanatory material, not approval or completion proof,
|
|
6935
|
+
and a visual-only turn does not clear the task's no-write advisory.
|
|
6936
|
+
|
|
6937
|
+
Periodic snapshots and task lists read bounded metadata only. Full payload
|
|
6938
|
+
screening happens on an explicit show; image reads still check current privacy,
|
|
6939
|
+
existence and hash at the asset route. A moved or deleted image leaves the public
|
|
6940
|
+
caption/text/alt record readable but cannot serve its old bytes.
|
|
6941
|
+
|
|
6942
|
+
A recovery refusal asks you to retry after `ahub status` shows the hold released.
|
|
6943
|
+
Role or membership refusals name the missing authority, and a task/config change
|
|
6944
|
+
asks for a retry. If the privacy screen is unavailable, restore the configured screen and retry;
|
|
6945
|
+
if the visual exceeds its input limit, shorten the text first. Private context, paths and pattern hits
|
|
6946
|
+
retain a uniform privacy refusal. Rate limits are checked before expensive
|
|
6947
|
+
screening or file reads and checked again at publication.
|
|
6948
|
+
|
|
6949
|
+
Task-bound visuals live with their task. Unbound records expire after 30 days;
|
|
6950
|
+
`visuals.retention_days` is an integer setting from 1 to 3650 days, applied live,
|
|
6951
|
+
with the normal authority guard on raising retention. Expired/removed records
|
|
6952
|
+
are unavailable even before a maintenance prune runs. No documentation stamp or
|
|
6953
|
+
real-home policy change is performed by posting a visual.
|
|
6954
|
+
|
|
6955
|
+
## Agent-authored records
|
|
6956
|
+
|
|
6957
|
+
Headless Record handling follows amem's effective machine and repository policy. Set `records: false` in the amem configuration to disable instruction, capture and Record preference; repository policy can only narrow machine policy. There is no hub-only override. Private or unverified contexts fail closed for capture without preventing ordinary answer routing.
|
|
6958
|
+
|
|
6959
|
+
Upgrade every amem consumer sharing a memory home together, including native CLI hooks and embedded hub/plugin copies. A 0.22.1 hook drain silently discards Record format-3 spool entries without a counted loss, and its config parser refuses the `records` key even when false, so set `records: false` only after every consumer is upgraded. The hub exact-pins 0.23.1 and uses its public `recordsEnabled` accessor for the active home and execution repository; it does not upgrade the other consumers automatically. No real home is migrated by the feature's fixtures.
|
|
6960
|
+
|
|
6961
|
+
Count-only `records capture`, `records forwarded`, `records brief` and `records recall` diagnostics report accepted/dropped rows or before/after UTF-8 bytes. Record text, anchors, native session IDs and credentials are absent from these diagnostics. An absent registry proof or an unavailable Record source preserves old note content; a privacy or policy change during a read withholds the stale block.
|