@staix/agent-hub 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +13 -7
- package/docs/agent-notes/README.md +1 -0
- package/docs/agent-notes/adapters.md +5 -2
- package/docs/agent-notes/budget.md +1 -0
- package/docs/agent-notes/bus.md +9 -4
- package/docs/agent-notes/daemon.md +15 -8
- package/docs/agent-notes/local-worker.md +1 -0
- package/docs/agent-notes/tasks.md +7 -3
- package/docs/agent-notes/tests.md +6 -4
- package/docs/design/adapters.md +52 -0
- package/docs/design/agent-hub-architecture.md +46 -0
- package/docs/design/bus.md +139 -1
- package/docs/design/task-board.md +82 -0
- package/docs/dogfood.md +22 -4
- package/docs/events.md +3 -0
- package/docs/memory.md +17 -1
- package/docs/operations.md +307 -78
- package/docs/profiles.md +35 -0
- package/docs/quickstart.md +18 -5
- package/docs/security.md +154 -60
- package/docs/specs/2026-09-19-agent-hub-design.md +84 -14
- package/docs/specs/2026-09-19-multi-project-design.md +7 -2
- package/docs/verification/2026-11-04-1171-channel-client-evidence.md +31 -0
- package/docs/verification/2026-11-05-0.31.0.md +182 -0
- package/docs/verification/2026-11-05-claude-implementer-2.1.318.md +70 -0
- package/docs/verification/2026-11-05-hardcoded-values-classification-rules.md +257 -0
- package/docs/verification/2026-11-05-hardcoded-values-ratchet.md +55 -0
- package/docs/verification/2026-11-06-rooms-presence-cost.md +152 -0
- package/docs/verification/claude-shell-wrapper-native.py +1 -1
- package/docs/verified.json +14 -14
- package/package.json +3 -4
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +4393 -3609
- package/src/adapters/acp.ts +5 -4
- package/src/adapters/channel-peer.ts +72 -3
- package/src/adapters/claude-channel-evidence.ts +52 -0
- package/src/adapters/claude-channel.ts +61 -18
- package/src/adapters/claude-implementer.ts +29 -7
- package/src/adapters/claude-print-child.ts +12 -2
- package/src/adapters/codex-appserver.ts +13 -12
- package/src/adapters/compat.ts +3 -3
- package/src/adapters/definitions/builtin-metadata.ts +13 -13
- package/src/adapters/definitions/qwen.ts +1 -0
- package/src/adapters/local-worker.ts +61 -18
- package/src/adapters/pi.ts +48 -6
- package/src/adapters/registry-types.ts +12 -0
- package/src/adapters/registry.ts +2 -0
- package/src/adapters/reviewer-print.ts +50 -11
- package/src/broker/server.ts +44 -13
- package/src/broker/store.ts +38 -8
- package/src/cli/answer-args.ts +50 -0
- package/src/cli/attention.ts +17 -2
- package/src/cli/backlog-return-args.ts +37 -0
- package/src/cli/console-question.ts +110 -0
- package/src/cli/console-state.ts +77 -16
- package/src/cli/console.ts +54 -1
- package/src/cli/handoff-args.ts +15 -5
- package/src/cli/handoff-output.ts +15 -2
- package/src/cli/help.ts +8 -5
- package/src/cli/identity.ts +13 -3
- package/src/cli/main.ts +128 -16
- package/src/cli/memory.ts +107 -3
- package/src/cli/output.ts +29 -6
- package/src/cli/pet.ts +4 -4
- package/src/cli/results-args.ts +30 -0
- package/src/cli/runtime-version-warning.ts +50 -0
- package/src/cli/status-lines.ts +41 -1
- package/src/cli/tail-render.ts +1 -0
- package/src/cli/upgrade-interactive.ts +14 -2
- package/src/hub/action-class.ts +9 -1
- package/src/hub/board.ts +369 -18
- package/src/hub/bus.ts +493 -53
- package/src/hub/completion-detail.ts +50 -0
- package/src/hub/completions-store.ts +168 -0
- package/src/hub/completions.ts +120 -0
- package/src/hub/config-apply.ts +7 -5
- package/src/hub/config-reload.ts +10 -1
- package/src/hub/control-client.ts +40 -4
- package/src/hub/daemon.ts +1569 -134
- package/src/hub/delivery-failure.ts +14 -0
- package/src/hub/delivery-hints.ts +14 -4
- package/src/hub/delivery-journal.ts +751 -42
- package/src/hub/delivery-superseded.ts +4 -1
- package/src/hub/envelope.ts +3 -3
- package/src/hub/events.ts +6 -0
- package/src/hub/handoff.ts +145 -6
- package/src/hub/hub-tools.ts +56 -7
- package/src/hub/manager.ts +59 -3
- package/src/hub/memory-policy.ts +44 -1
- package/src/hub/memory-sync-policy.ts +109 -0
- package/src/hub/memory-sync-state.ts +145 -0
- package/src/hub/no-writes.ts +1 -1
- package/src/hub/operational-settings.ts +11 -2
- package/src/hub/operational-view.ts +12 -1
- package/src/hub/peers.ts +25 -2
- package/src/hub/planning.ts +6 -1
- package/src/hub/question-desk.ts +201 -0
- package/src/hub/question-detach.ts +6 -0
- package/src/hub/questions.ts +260 -0
- package/src/hub/research-evidence.ts +106 -0
- package/src/hub/restart.ts +14 -0
- package/src/hub/review-anchor.ts +181 -0
- package/src/hub/review-brief.ts +13 -0
- package/src/hub/review-comments.ts +115 -0
- package/src/hub/review-findings.ts +7 -2
- package/src/hub/review-material.ts +76 -0
- package/src/hub/routing.ts +3 -1
- package/src/hub/task-sweep.ts +2 -0
- package/src/hub/tasks.ts +577 -63
- package/src/memory/capture.ts +5 -2
- package/src/pet/config.ts +25 -13
- package/src/rooms/link.ts +209 -21
- package/src/rooms/remote-peer.ts +186 -19
- package/src/rooms/service.ts +338 -22
- package/src/rooms/store.ts +437 -65
- package/src/rooms/wire.ts +24 -6
- package/src/ui/index.html +138 -7
- package/src/ui/needs.ts +10 -4
- package/src/ui/plugin-questions.ts +56 -0
- package/src/ui/plugin-results.ts +81 -0
- package/src/ui/plugin.ts +207 -27
- package/src/pet/window.html +0 -114
- package/src/pet/window.jxa.js +0 -122
- package/src/pet/window.ts +0 -154
|
@@ -803,7 +803,9 @@ atomically install that candidate against its persisted pin. Replaying an old
|
|
|
803
803
|
candidate must never reset the minimum epoch or a grace deadline.
|
|
804
804
|
|
|
805
805
|
A frame's public header is `{v,type,room,epoch,sender,recipients,seq}` plus nonce,
|
|
806
|
-
ciphertext and signature.
|
|
806
|
+
ciphertext and signature. Presence may add the signed optional `ephemeral: true`
|
|
807
|
+
header (#1204 T1); every other value for that optional field refuses. Recipients
|
|
808
|
+
are hub fingerprints, not local peer ids.
|
|
807
809
|
The body is opaque encrypted bytes, including any eventual local addressing,
|
|
808
810
|
kind, trace and text. Frame AAD is exactly UTF-8 `room|epoch|sender|seq`. A
|
|
809
811
|
sender-specific AES key is HKDF-derived from the epoch root and room/epoch/sender/
|
|
@@ -974,7 +976,14 @@ survive queue ACKs/restart: the last accepted digest or an identical retained ol
|
|
|
974
976
|
packet is idempotent without requeueing; conflicting or
|
|
975
977
|
unknown lower sequences refuse. FIFO uses SQLite admission row order, never lexical
|
|
976
978
|
sequence strings or clock ties. Full queues refuse new packets without evicting
|
|
977
|
-
accepted ones.
|
|
979
|
+
accepted durable ones. Ephemeral presence replaces only prior ephemeral rows of
|
|
980
|
+
that sender and retains only currently ready recipients; disconnect/restart
|
|
981
|
+
removes those recipients, while sender floors and durable work remain. The same
|
|
982
|
+
queue/byte caps still apply. A frame-level `queue_full` includes its verified
|
|
983
|
+
digest. Links retain the sealed frame and retry after 250 ms, doubling to 30 s,
|
|
984
|
+
with one frame awaiting storage acceptance so later sequences cannot overtake it.
|
|
985
|
+
Applications stay in the local outbox; T2 owns receipt persistence and deadline/
|
|
986
|
+
restart replay changes. Prior-epoch grace may expire a packet before its ordinary TTL.
|
|
978
987
|
|
|
979
988
|
One packet per recipient socket is in flight. `{v:1,type:"received",digest}` removes
|
|
980
989
|
only that identity from the packet's remaining recipients, then returns
|
|
@@ -1114,6 +1123,16 @@ not project config or synced memory. A hub stop closes links and retains members
|
|
|
1114
1123
|
A person may explicitly import a pinned signed roster to reactivate a left room;
|
|
1115
1124
|
automatic link traffic cannot reactivate it.
|
|
1116
1125
|
|
|
1126
|
+
|
|
1127
|
+
The optional ephemeral field is used only after an opted-in connection receives
|
|
1128
|
+
`ephemeral: true` in the broker ready control. The upgrade header is
|
|
1129
|
+
`x-agent-hub-ephemeral: 1`; brokers preserve the old closed ready shape for
|
|
1130
|
+
clients that do not opt in. Missing advertisement means legacy presence frames,
|
|
1131
|
+
with dedupe/backoff still active. The broker withholds ephemeral frames from older member hubs
|
|
1132
|
+
until upgraded; application chat stays wire-compatible. See the [compatibility
|
|
1133
|
+
ceiling](../design/bus.md#room-wire-compatibility-1204-t1); #1204 T4 owns full codec
|
|
1134
|
+
feature negotiation.
|
|
1135
|
+
|
|
1117
1136
|
### Durable state and outbound link
|
|
1118
1137
|
|
|
1119
1138
|
`<hub-state>/rooms/rooms.db` is schema version 1, SQLite DELETE/EXTRA with exclusive
|
|
@@ -1152,9 +1171,12 @@ at most 8 pending packets/2 MiB per link, 1 MiB packet/backpressure limits and a
|
|
|
1152
1171
|
minutes and do not block local work. Stop, leave, replacement and rotation fence
|
|
1153
1172
|
all awaited work by link generation.
|
|
1154
1173
|
|
|
1174
|
+
With latest-per-sender coalescing, A awaiting C can have its queued request replaced by A's broadcast reply to B, so C sees the request only on A's next state change or reconnect; task #736 idle refresh or per-(sender,recipient) coalescing is the upgrade path.
|
|
1175
|
+
|
|
1155
1176
|
Presence is an encrypted, signed frame containing only exposed peer ids and closed
|
|
1156
1177
|
idle/busy/paused/offline states. It is sent on connection and coalesced peer-state
|
|
1157
|
-
changes,
|
|
1178
|
+
changes, skipping identical snapshots except explicit peer refresh exchanges,
|
|
1179
|
+
never titles, bodies, private task context or credentials. Unknown payload
|
|
1158
1180
|
types and unexposed ids refuse before replay commit. Broker ACKs are transport
|
|
1159
1181
|
facts only. A canonical room/recipient-bound frame that is refused or stale is
|
|
1160
1182
|
recorded in a durable metadata-only drop ledger before transport retirement ACK.
|
|
@@ -1256,15 +1278,20 @@ exposed local peer's queue**. It does not mean native or model execution. Person
|
|
|
1256
1278
|
views say **completed (admitted)**. Broker `stored` means accepted ciphertext
|
|
1257
1279
|
only; a transport retirement ACK is not application completion.
|
|
1258
1280
|
|
|
1259
|
-
|
|
1281
|
+
Schema5 retains a nullable canonical outgoing content hash. Cross-root reuse of
|
|
1282
|
+
a retained application requires matching content and peer/recipient, no disposition
|
|
1283
|
+
or permanent hold, and inherited creation/expiry times; legacy NULL refuses it.
|
|
1284
|
+
Schema5 of the private `rooms.db` migrates schema1 through 4 without replacing identity,
|
|
1260
1285
|
pins, counters, floors or retained traffic. A receiver commits its crypto inbox,
|
|
1261
1286
|
then application `pending -> dispatching` before publishing into the separate
|
|
1262
1287
|
Bus journal. A crash or failure in that cross-DB publication window becomes
|
|
1263
|
-
`needs_review`, with no automatic republish or fabricated receipt.
|
|
1264
|
-
`dispatching`/`accepted` rows
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1288
|
+
`needs_review`, with no automatic receiver republish or fabricated receipt.
|
|
1289
|
+
Sender `dispatching`/`accepted` rows recover from validated durable intent under
|
|
1290
|
+
the same application and delivery ids, retaining their original queue expiry.
|
|
1291
|
+
A valid late signed receipt may settle an unresolved ordinary sender hold;
|
|
1292
|
+
invocation uncertainty remains person-settled. Person dispositions and invalidated
|
|
1293
|
+
recipient bindings remain authoritative. Signed
|
|
1294
|
+
remote safe refusals are terminal; native poison-envelope policy is unchanged.
|
|
1268
1295
|
|
|
1269
1296
|
Signed seq/floors are the permanent primary replay protection. Duplicate seqs
|
|
1270
1297
|
are retired without a second admission; a known identical completed application
|
|
@@ -1275,6 +1302,9 @@ oldest settled rows are evicted first. Pending, dispatching and unresolved
|
|
|
1275
1302
|
`needs_review` are never evicted. An all-unsettled cap refuses with the room and
|
|
1276
1303
|
count. Outside retention or after settled eviction, there is no historical
|
|
1277
1304
|
app-id dedupe claim; an old signed frame is still refused by its seq floor.
|
|
1305
|
+
Automatic resend can reach this settled-eviction ceiling and repeat admission
|
|
1306
|
+
under a fresh ciphertext sequence: exactly once within dedupe ceiling. Pinning
|
|
1307
|
+
retryable identities or #737 receipt confirmation is the upgrade path.
|
|
1278
1308
|
|
|
1279
1309
|
The trace high-water mark is kept for the tombstone retention (30 days / 10,000
|
|
1280
1310
|
per room, settled rows evicted first); outside it there is no historical trace
|
|
@@ -1288,16 +1318,17 @@ Offline Bus queues count toward the 200-per-room ceiling before transport starts
|
|
|
1288
1318
|
`hub_send` refuses beyond it. Original host deadlines survive handoff and restart.
|
|
1289
1319
|
Unknown legacy deadlines fail closed to `needs_review`. Machine-local
|
|
1290
1320
|
`rooms.ack_timeout_s` defaults to 600 (1..86,400); `rooms.queue_ttl_h` defaults to
|
|
1291
|
-
24 (1..168). A single deadline-driven host timer handles
|
|
1292
|
-
|
|
1321
|
+
24 (1..168). A single deadline-driven host timer handles ACK retries and queue
|
|
1322
|
+
expiry. Only validated durable sender intent is retried automatically; missing
|
|
1323
|
+
or corrupt local evidence remains held. Explicit terminal-history retries without
|
|
1293
1324
|
recipient proof refuse; the person can author a fresh message deliberately.
|
|
1294
1325
|
An expired or missing original enqueue deadline also refuses a person retry
|
|
1295
1326
|
before any disposition is recorded; a retry never invents a fresh TTL.
|
|
1296
1327
|
|
|
1297
1328
|
The ACK deadline starts at durable application handoff, before a broker `stored`
|
|
1298
|
-
reply, and is never extended by that reply.
|
|
1299
|
-
|
|
1300
|
-
|
|
1329
|
+
reply, and is never extended by that reply. Its expiry schedules another attempt
|
|
1330
|
+
under the same application id, without resetting the original queue TTL. Queue
|
|
1331
|
+
expiry or a permanent refusal ends automatic sending. Known pre-admission capacity or journal-unavailable refusals retain
|
|
1301
1332
|
their pending plaintext for the next online/disposition retry without preventing
|
|
1302
1333
|
later room packets and receipts from being processed. Status reads apply no
|
|
1303
1334
|
disposition. Settled chat plaintext rows are pruned independently of presence
|
|
@@ -2782,6 +2813,12 @@ push `accepted` and show none of them.
|
|
|
2782
2813
|
sources add protocol 15 (0.12.17 through 0.12.19); the transition from a real
|
|
2783
2814
|
0.12.19 hub is not yet proven.
|
|
2784
2815
|
|
|
2816
|
+
## Amendment: inherited Claude channel marker requires direct-parent evidence (issue #1171)
|
|
2817
|
+
|
|
2818
|
+
- `AGENTHUB_CHANNEL=1` alone does not enable push. Claude Code child processes, including `daemon run` and `bg-spare`, inherit it without the development-channel flag. The plugin's direct parent must have a bounded, readable `ps -ww` row whose leading argv tokens are `claude --dangerously-load-development-channels` and one exact supported target (`plugin:agent-hub@agent-hub` or `server:agent-hub`). Print/background/daemon forms, a repeated development-channel flag, unreadable or malformed output, a changed parent pid, and unknown targets fail closed to tools-only.
|
|
2819
|
+
- The classifier is conservative because `ps` renders a flattened command line; matching is restricted to the prefix and remaining tokens are checked for known mode-changing forms. This is same-user process observation, not authentication. No client-side Claude channel capability was found in the inspected Claude Code 2.1.318 client path, and the server's own advertised capability is not proof. Unknown evidence keeps messages queued for `hub_inbox`.
|
|
2820
|
+
- `status.json` reports `attachMode` and a closed `attachEvidence` label for an attached Claude peer; human `ahub status` shows the same pair. Older clients that omit the evidence field retain their prior attachment behavior and display `unreported`.
|
|
2821
|
+
|
|
2785
2822
|
## Amendment: channel queue visibility and explicit pull (issue #493)
|
|
2786
2823
|
|
|
2787
2824
|
- A channel session's `hub_inbox` reads the daemon queue through the same
|
|
@@ -3945,6 +3982,8 @@ run has no hub command lineage.
|
|
|
3945
3982
|
|
|
3946
3983
|
## Amendment: standalone attention window (#391 Task B, supersedes #280 dashboard pet)
|
|
3947
3984
|
|
|
3985
|
+
Historical surface, retired by #1012. Current presentation contract: [console surfaces](../design/agent-hub-architecture.md#console-presentation-surfaces).
|
|
3986
|
+
|
|
3948
3987
|
The #280 phase-4 dashboard pet is replaced by an optional standalone macOS JXA
|
|
3949
3988
|
window. Task B adds the window first; #391 Task A removes the existing in-page
|
|
3950
3989
|
character and retains shared attention counts/navigation. Terminal characters
|
|
@@ -6452,3 +6491,34 @@ Each pack supplies criterion ids in its rubric and exactly one advisory check en
|
|
|
6452
6491
|
## Amendment: research campaigns, experiment receipts and runner attestation (#930, #932, #1018)
|
|
6453
6492
|
|
|
6454
6493
|
The implementation contract for #929 R1 and R3 and for #1018 is `docs/specs/2026-11-01-research-campaigns-design.md`: campaign, protocol, attempt and receipt schemas and bounds; the provenance levels `declared`, `host-observed`, `runner-attested` and `person-attested`; the Board tables; the person-only activation, attestation and runner registration; the `ahub study` and `hub_study_*` / `hub_experiment_*` wire names; the `research_records` recovery feature; and the delivery slices (#596 to #602). Slices that must differ amend that document in their own PR.
|
|
6494
|
+
|
|
6495
|
+
## Amendment: anchored review packages (#1056)
|
|
6496
|
+
|
|
6497
|
+
The current contract is recorded in [Task Board](../design/task-board.md#anchored-review-packages-1056). Optional finding anchors use the published acon review shape, with stricter hub UTF-8 write bounds. Person drafts are board-local until one explicit console-authorized Send creates one immutable package and one count-only history entry. Owner completion can claim sent comment IDs resolved without claiming person verification. Placement is recomputed over guarded task-scoped Git/projection material; stored anchors never move.
|
|
6498
|
+
|
|
6499
|
+
The acon plugin uses `ActionMeta` and `host.ui.review` from the published DOM-free 0.1.3 contract as types only; there is no new runtime dependency or renderer. A private/PII view withholds text, and trusted package markers exclude quote/body content from logs, tails, incoming labels and memory capture without making a public task private. Recovery sections are optional for older snapshots. The owner's live document package-format confirmation remains a separate manual check; fixture and code evidence do not claim that confirmation.
|
|
6500
|
+
|
|
6501
|
+
### Receipt publication ordering (#1204 T2)
|
|
6502
|
+
|
|
6503
|
+
A chat ciphertext transport ACK follows the signed receipt ciphertext's local
|
|
6504
|
+
durable RoomStore outbox commit. The receipt replays after reconnect or restart
|
|
6505
|
+
until the broker confirms storage. Waiting for broker storage before the chat ACK
|
|
6506
|
+
would deadlock at capacity one. No receipt or native completion is inferred from
|
|
6507
|
+
socket send alone.
|
|
6508
|
+
ACK after durable local commit of either the receipt or the inbox entry.
|
|
6509
|
+
Deferred application admission retains the durable crypto inbox entry, ACKs the
|
|
6510
|
+
chat to free broker capacity, and later commits its final receipt to the same
|
|
6511
|
+
durable outbox when admission resumes.
|
|
6512
|
+
|
|
6513
|
+
A session keeps its refresh request pending for every asked recipient until a
|
|
6514
|
+
validated presence from that member arrives. Later non-reply snapshots retain
|
|
6515
|
+
requestReply while anyone is pending; replies never carry requestReply. The set
|
|
6516
|
+
is bounded by the current roster and resets at reconnect or membership change.
|
|
6517
|
+
|
|
6518
|
+
Room application retries preserve the application id, canonical delivery id and
|
|
6519
|
+
original queue TTL, using a fresh authenticated ciphertext sequence where needed.
|
|
6520
|
+
The ACK timeout schedules resend rather than uncertainty; queue expiry or a
|
|
6521
|
+
permanent refusal remains inspectable. A signed late receipt may settle an
|
|
6522
|
+
unresolved ordinary remote hold once without overriding a person disposition.
|
|
6523
|
+
Invocation uncertainty retains its person-only ledger hold. Receiver application
|
|
6524
|
+
deduplication, current identity/privacy fences and all caps remain.
|
|
@@ -99,8 +99,13 @@ visual redesign, automatic merging and npm publication.
|
|
|
99
99
|
Same-machine cross-project routing is no longer out of scope: work that belongs to another project that runs agent-hub is registered on that project's board.
|
|
100
100
|
|
|
101
101
|
- **Target.** `project` names a project in the machine registry (its canonical root or its id). An unregistered target, the caller's own project and a target whose daemon is not running are refused, the last with the person's action (`ahub up` in that project). Nothing is queued.
|
|
102
|
-
- **Who and what.** The person (`ahub task handoff --project <root|id> [<class>] <title...> [--path <p>]... [--issue <n>] [--task <n>] [--detail <text>]`), or a configured planner or the conductor (`hub_task_handoff`). A feature or behavior change first needs a spec issue in the target repository, passed as `issue`; a mechanical chore goes straight to a task. The request is closed (unknown fields refused), bounded (8 KiB whole) and repository-relative for paths.
|
|
102
|
+
- **Who and what.** The person (`ahub task handoff --project <root|id> [<class>] <title...> [--path <p>]... [--issue <n>] [--task <n>] [--detail <text>] [--duplicate-ok <reason>]`), or a configured planner or the conductor (`hub_task_handoff`). A feature or behavior change first needs a spec issue in the target repository, passed as `issue`; a mechanical chore goes straight to a task. The request is closed (unknown fields refused), bounded (8 KiB whole) and repository-relative for paths.
|
|
103
103
|
- **Transport.** The origin's daemon reads the target's control descriptor (same machine user) and sends `task_handoff` as a console-role control message with origin `{ projectId, peer, taskId? }`. The target's `Tasks` creates an ownerless proposal made by the hub, with the origin recorded in `task_handoff_origin`; its own routing and planner take it from there. The origin peer has no identity or authority in the target: it is a record, never a roster peer.
|
|
104
104
|
- **Follow-back.** On accepted, in review, approved, declined and cancelled the target sends `task_handoff_event`; the origin records it in `task_handoff_outbound` and delivers one `kind: task` envelope to the requesting peer (`agent-hub task 123 approved: PR #N at <sha>`: an event name, a PR number and a full head, never target text). An origin that was down asks the target for the current state of its open handoffs when it starts (`task_handoff_states`). `ahub board --handoffs` and `hub_task_handoffs` list them.
|
|
105
|
+
- **Duplicates and cancel (#1175).** A handoff naming a spec issue (`issue`) that already has an open task on the target's board (proposed, backlog, in progress, in review or changes requested; a `[pii]` row is never named) is refused before any row exists, with the open task ids, unless the sender passes `duplicate_ok` (a reason of up to 300 characters, recorded in the task's detail). An issue number identifies work only together with its repository: `sdlc.repo`, `external {repo, issue}` (an imported backlog row) and a slug `refs.repo` that name another repository than the target's do not count. The target's configured, rostered conductor may cancel a handed-off task that nobody has accepted and that has no execution evidence, with a reason; the origin hears `cancelled` through the follow-back, never the reason. A target from before this check refuses `duplicate_ok` as an unknown field, which the sender reports as "upgrade the target hub or hand off without `duplicate_ok`".
|
|
106
|
+
- **Idempotent request (#1203 T1).** The origin mints a `handoffKey` (UUID v4) per request, or takes the one a retry passes (`--key`, `handoffKey`), and sends it in the `task_handoff` request body to a target that advertises `task_handoff_key`. The target stores it with a digest of what was asked in `task_handoff_origin` (unique per origin project) and writes the proposal and the origin row in one board transaction (`Board.proposeHandoff`). A key it already holds answers with that task (`replayed`) before the duplicate check and before any PII screen; the same key for a different request is refused. A timeout or a closed connection is not a refusal: the origin sends the same key once more, then asks the target by key (`task_handoff_by_key`, answered only to the asking project and only with the fields a live event carries), and otherwise reports the new refusal code `outcome_unknown`, naming the key to retry with. The origin records its outbound row from the reply or the by-key answer, never resetting a row that already exists.
|
|
107
|
+
- **Converging follow-back (#1203 T2).** Each `task_handoff_event` carries `seq`, the target task's flow revision (its history length), to an origin that advertises `task_handoff_seq`. The origin keeps the sequence of the last applied event in the outbound row and ignores an event whose `seq` is not newer: it changes nothing and sends no envelope, decided inside the one board write, so events that arrive out of order (each uses its own connection) cannot move a row backwards. An event without `seq` (an older target) applies as before. The origin's catch-up (`task_handoff_states`, which now also returns `seq`) runs at start, every 5 minutes and when a target's control descriptor changes, over every row that is not cancelled and, for an approved one, was updated within the last 7 days (a reviewer can withdraw an approval; the origin only learns of it through the sequence), with no 200-row cap and in requests of at most 200 task ids. `changes_requested` and `reopened` are events, sent only to an origin that advertises `task_handoff_seq`. A catch-up pass never overlaps another, never holds a board write and stops at shutdown. `ahub board --handoffs` still lists the 200 most recently changed rows; that cap is for display only.
|
|
108
|
+
- **Diagnostics and repair (#1203 T3).** Every failure is visible and repairable by the person. A connection to a target that fails is named by the error's code and never by its message: 4426 (the wire versions share no protocol) is `older_target` and says to upgrade whichever hub is older, 4404 (another hub or instance answers) is the new refusal code `mismatch` and says to check `ahub projects`, a connect timeout says the hub may be stuck (`ahub status`), and only an unreachable hub says "not running" with `ahub up`. A failed notify, catch-up pass or handoff writes one `hub.log` line per target and cause in each window (15 minutes), with a fixed cause phrase and never a task title or the target's text. `ahub task handoff --list` (the person's command, read-only) shows each handoff with its age since the last report and `reachable`, `unreachable` with its cause and next step, or `moved` (the project id is not in the machine registry: it was removed or its root changed, and the id is a hash of the root), read from the registry and the target's descriptor file without opening a connection. `ahub task handoff --sync` (the person or the conductor) runs a catch-up pass now and answers with the refreshed list; it waits for a pass already running and then runs its own, for at most 20 seconds (under the caller's 30 second control timeout, because the pass asks targets one after another): past that it answers with the list as it stands, `syncing: true` and the number of targets still pending, the pass goes on in the background, and the CLI prints "catch-up still running for N targets: run `ahub task handoff --list` in a minute". An agent gets the same list from `hub_task_handoffs` (now with `age`, `ageMs`, `reach` and `cause`) and cannot sync. A catch-up request that gets no usable reply (the target refused it, timed out or dropped the connection) is a failure like any other: its target reads `unreachable` with the cause "no answer to the state request" and the step `ahub status` in that project, one log line is written, and the earlier failure is not cleared. If the pass itself fails, `--sync` answers `synced: false` with that cause instead of `synced: true`.
|
|
109
|
+
- **Follow-back envelope (#1203 T1).** It carries `refs.handoff {project, task}` (the target's project and task) and no `refs.task`, so the bus never judges it against a local task that happens to have the same number; the one-line body is unchanged.
|
|
105
110
|
- **Privacy.** Refused during a private (PII) turn and for a `[pii]` task named with `task`; the target refuses text that matches a PII pattern or that its screen cannot clear. No memory, evidence or turn content crosses beyond the handoff fields.
|
|
106
|
-
- **Compatibility.** The additive daemon
|
|
111
|
+
- **Compatibility.** The additive daemon features `task_handoff` and, from #1203 T1, `task_handoff_key` and `task_handoff_seq` (the latter: a target sends `seq` and the two new events only to an origin that has it; an origin ignores a missing `seq`). `task_handoff_key` (an origin sends no key to a target without it and keeps the earlier behavior, a timeout there is `outcome_unknown` without a retry key, and the request is not repeated). Neither feature bumps the protocol: a new message type is answered as unknown by an older hub, and an optional field is ignored, except `duplicate_ok` and `handoffKey`, which an older target refuses as unknown fields (so the key is sent only to a target that advertises it). An older target is refused with a named "upgrade the target hub" error, and a recovery target without the label is refused while either handoff table holds a row.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Channel client evidence for #1171
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
This investigation checked the installed first-party Claude Code 2.1.318 artifact and read process metadata on macOS on 2026-11-04. It did not start a model session, modify a running client, capture a live MCP handshake, or establish that a particular notification reached a model.
|
|
6
|
+
|
|
7
|
+
The artifact was the existing native installation at `~/.local/share/claude/versions/2.1.318`. Its embedded build metadata names Git revision `ca1fa9dea62c1027756786c841c548788644560d` and build time `2026-11-03T18:52:53Z`.
|
|
8
|
+
|
|
9
|
+
## Client initialization and channel registration
|
|
10
|
+
|
|
11
|
+
The inspected stdio MCP client construction passes capabilities through `_Xt`, `pOn` or `uOn`, and `W`. That path builds roots/list-change and elicitation capabilities, with conditional MCP application extensions. The inspected path contains no channel-specific client capability or flag-dependent channel opt-in field.
|
|
12
|
+
|
|
13
|
+
Channel registration is a separate path. It checks the server's channel declaration, protocol compatibility, provider and organization policy, and the session's selected channel entries. A generic MCP client capability therefore cannot establish that this session opted into this channel. This is a bounded observation about these paths in 2.1.318, not a claim about every client version.
|
|
14
|
+
|
|
15
|
+
The [official channel reference](https://code.claude.com/docs/en/channels-reference) describes the channel capability as a server declaration. It also documents the development flag as interactive-only; print mode ignores that flag. No usable client initialization signal was found in the inspected artifact and reference.
|
|
16
|
+
|
|
17
|
+
## Direct-parent fallback
|
|
18
|
+
|
|
19
|
+
The existing `claudeNativeLaunch` implementation prepends the development-channel flag and a selected exact target before native passthrough arguments. The target is normally `plugin:agent-hub@agent-hub`; its existing matching MCP configuration path can select `server:agent-hub`.
|
|
20
|
+
|
|
21
|
+
A passive process observation corroborated this layout for the running native TUIs: process 10310 and several other observed TUIs had the exact known flag/target prefix. The observed background daemon, process 17739, did not. Two other Claude process rows exposed only the process name, which cannot establish support. The observation emitted only identifiers and classification results, without retaining command bodies, paths or prompts.
|
|
22
|
+
|
|
23
|
+
The proposed fallback was communicated to the reviewer before implementation: require the existing launcher marker together with bounded evidence from the direct parent's actual invocation. An inherited marker alone is insufficient. Unknown process metadata must remain tools-only. Searching an arbitrary command substring would be unsafe because a prompt or an option value can contain the same flag text.
|
|
24
|
+
|
|
25
|
+
The flag evidence has a deliberate ceiling: it establishes the inspected launch form, not organization policy, user confirmation, protocol registration or model consumption. Unrecognized launch forms must remain pull-only. The separate #1172 settlement work is needed for notifications that are accepted by the transport but never confirmed by the session.
|
|
26
|
+
|
|
27
|
+
## Verification boundaries
|
|
28
|
+
|
|
29
|
+
Synthetic fixtures must distinguish an inherited marker without parent evidence from the supported launcher form, and keep the former's messages readable through `hub_inbox`. Negative cases include print/background forms, repeated or misplaced flags, unknown targets and unavailable process metadata. Status must expose a closed evidence value, never command text.
|
|
30
|
+
|
|
31
|
+
Source tests, the committed-head remote gate, hosted CI and native message-consumption receipts are separate evidence. This investigation supplies no native delivery receipt.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# 0.31.0 release verification
|
|
2
|
+
|
|
3
|
+
This record covers release preparation and source review. It claims no installation, no running-hub upgrade to 0.31.0 and no live TUI launch.
|
|
4
|
+
|
|
5
|
+
## Candidate
|
|
6
|
+
|
|
7
|
+
Initial preparation: version 0.31.0, prepared from main 3185dd4c (33 commits since v0.30.0; the tool's count of 34 includes this branch's CHANGELOG commit 7e2a3257, 16 of them `feat`; bump rule: minor). The release commits carry the version, the CHANGELOG section, the bundle and the documentation stamps.
|
|
8
|
+
|
|
9
|
+
## Completion after the release follow-ups (task 744)
|
|
10
|
+
|
|
11
|
+
The single intended release remains 0.31.0. Completion starts from main
|
|
12
|
+
`9e4f24c3b222b6faa40309eeb0a91a54107dfe6e` on the exact branch
|
|
13
|
+
`release/0.31.0`; no version, runtime, bundle or fixture version is changed here.
|
|
14
|
+
At preparation, npm's `latest` was 0.30.0 and the remote `v0.31.0` tag was absent.
|
|
15
|
+
The earlier release PRs #1218 and #1223 are already merged, but the four source
|
|
16
|
+
PRs below landed afterward. This follow-up must also be merged with a merge
|
|
17
|
+
commit and the default subject, preserving the reviewed-stamp ancestors for the
|
|
18
|
+
guarded tag. It neither records consent nor creates a tag or npm publication.
|
|
19
|
+
|
|
20
|
+
The board approval head equals each merged PR's head (`mismatch: false`).
|
|
21
|
+
GitHub readback found every listed check completed successfully or skipped,
|
|
22
|
+
with no failed or pending check. Counts below are head-specific hosted checks,
|
|
23
|
+
not installed/native acceptance or a new full-suite result for this docs branch.
|
|
24
|
+
|
|
25
|
+
| PR / task | Approved head | Merge commit | Hosted CI |
|
|
26
|
+
| --- | --- | --- | --- |
|
|
27
|
+
| [#1213](https://github.com/STAIxBWLB/agent-hub/pull/1213), task 739 | `6a304ccbdc2b9ab511f6f85af7fb8fbaee18f1ce` | `c58958d3a13c4de0317fdfb72745a88943315e93` | 19 success, 2 skipped |
|
|
28
|
+
| [#1224](https://github.com/STAIxBWLB/agent-hub/pull/1224), task 714 | `cf20b1d30fe314938c013b34b8a394e8aed1474f` | `b7408fffccdfcdce88fd0e04c2cbecf91c44d7c8` | 21 success, 2 skipped |
|
|
29
|
+
| [#1215](https://github.com/STAIxBWLB/agent-hub/pull/1215), task 734 | `4ffbab00e3a10a32c2955c76873b424f4d5434f8` | `4a4f87ed445bb32df13f9b371f8792dde740de65` | 19 success, 2 skipped |
|
|
30
|
+
| [#1228](https://github.com/STAIxBWLB/agent-hub/pull/1228), task 743 | `8c6d28bbd49f9d2b28e5ab62c28fd81d8a1e6f72` | `9e4f24c3b222b6faa40309eeb0a91a54107dfe6e` | 19 success, 2 skipped |
|
|
31
|
+
|
|
32
|
+
CHANGELOG now includes failure causes/unresolved failed counts, the handoff
|
|
33
|
+
reachability/repair diagnostics, the exact agent-mem 0.21.0 pin and complete
|
|
34
|
+
bounded declined inspection, and the missing task 739 convention entry.
|
|
35
|
+
Unreleased is empty. The old #1173 wait for agent-mem#260/#261 is replaced:
|
|
36
|
+
AC4 is complete, while automatic v3 sync remains unsupported pending the
|
|
37
|
+
activation and fresh host-attestation path in agent-mem#281. No activation or
|
|
38
|
+
attestation is fabricated. Task 736/T3 and task 737/T4 are not in this release.
|
|
39
|
+
|
|
40
|
+
The hub N-1 fixture stays 0.30.0 with agent-mem 0.20.1. The additive nullable
|
|
41
|
+
`deliveries.failure_cause` column does not raise hub schema version 2; the older
|
|
42
|
+
recovery reader ignores the extra diagnostic snapshot key. The existing
|
|
43
|
+
`peer_takeover` compatibility statement is retained. Memory claims are limited
|
|
44
|
+
to [agent-mem's published 0.21.0 notes](https://github.com/STAIxBWLB/agent-mem/blob/v0.21.0/CHANGELOG.md):
|
|
45
|
+
its N-1 proof uses 0.20.3, not the 0.20.1 bundled by hub 0.30.0. Those notes keep
|
|
46
|
+
curated/capture/hook-spool/candidate/work-list/setup receipt v1/v2 formats,
|
|
47
|
+
shared-v1/generation/v1-v2 shard sync and index version/name unchanged, and
|
|
48
|
+
record 0.20.3 refusing activated v3. This report does not extend that versioned
|
|
49
|
+
proof to 0.20.1 or claim supported v3 activation/automatic sync.
|
|
50
|
+
|
|
51
|
+
### Document review for task 744
|
|
52
|
+
|
|
53
|
+
The 14 stale documents were reviewed against the task 714, 734 and 743 deltas
|
|
54
|
+
only; task 739 changes classification metadata without runtime behavior.
|
|
55
|
+
Changed documents:
|
|
56
|
+
|
|
57
|
+
- `docs/quickstart.md`: correct the 0.31.0 upgrade paragraph, additive failure
|
|
58
|
+
column, current exact memory pin and the automatic-v3 limitation; retain the
|
|
59
|
+
historical 0.30.0 pin note and global CLI/plugin update step.
|
|
60
|
+
- `docs/operations.md`: correct the mismatch next step (`ahub projects`, with
|
|
61
|
+
`ahub up` conditional on the intended target not running).
|
|
62
|
+
- `docs/security.md`: correct the old 0.18.0 pin; distinguish safe status
|
|
63
|
+
placement counts from failure logging and bounded person-only inspection;
|
|
64
|
+
state the activation/attestation limitation.
|
|
65
|
+
- `docs/agent-notes/adapters.md`: carry typed structured failure diagnostics
|
|
66
|
+
without treating the diagnostic as settlement or trusting native text.
|
|
67
|
+
- `docs/agent-notes/bus.md`: preserve typed causes through persistence/retry,
|
|
68
|
+
use metadata-only unresolved counts, and distinguish unavailable from zero.
|
|
69
|
+
|
|
70
|
+
Reviewed without content changes:
|
|
71
|
+
|
|
72
|
+
- `README.md`: version/protocol and high-level memory/handoff claims remain true.
|
|
73
|
+
- `docs/agent-notes/README.md`: historical background is unchanged.
|
|
74
|
+
- `docs/agent-notes/benchmarks.md`: no benchmark protocol or end-cause change.
|
|
75
|
+
- `docs/agent-notes/budget.md`: quota/accounting and pause semantics are unchanged.
|
|
76
|
+
- `docs/agent-notes/daemon.md`: current policy/profile sync fences and handoff
|
|
77
|
+
diagnostic codes, authority and bounded sync behavior remain accurate.
|
|
78
|
+
- `docs/agent-notes/local-worker.md`: the watchdog cause is additive; cancellation
|
|
79
|
+
and uncertainty remain unchanged, with typed diagnostics owned by adapters.
|
|
80
|
+
- `docs/agent-notes/tasks.md`: task/handoff authority and the write-time memory
|
|
81
|
+
projection remain valid.
|
|
82
|
+
- `docs/agent-notes/tests.md`: fake boundaries, exact-pin fixtures and the
|
|
83
|
+
type-only overload adaptation do not change the test instructions.
|
|
84
|
+
- `src/cli/help.ts`: handoff `--list`/`--sync` match main and the argument parser;
|
|
85
|
+
status/queue/declined forms and native entry definitions are unchanged.
|
|
86
|
+
|
|
87
|
+
Only these 14 reviewed documents were restamped through
|
|
88
|
+
`bun scripts/release-prepare.ts restamp <document>... --reviewed` at the reviewed
|
|
89
|
+
content commit `af37f8fd8b44a2c566aa47629ec5b02ee9f91d69`. The stamp-only commit
|
|
90
|
+
`7db76b365d0b3e0ef0b946468193dab7b3393bd8` retains that ancestor; the already
|
|
91
|
+
fresh models document was not restamped.
|
|
92
|
+
|
|
93
|
+
### Completion checks for task 744
|
|
94
|
+
|
|
95
|
+
On dgx02, `remote_dev.py verify` checked committed head
|
|
96
|
+
`7db76b365d0b3e0ef0b946468193dab7b3393bd8` (tree `656a468fbfd1`) with
|
|
97
|
+
`node scripts/check-docs.mjs --require-fresh && scripts/check.sh --changed`.
|
|
98
|
+
The run completed in 31 seconds with:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
docs: OK (0 stale documents)
|
|
102
|
+
roles: OK (17 bounded definitions)
|
|
103
|
+
inventory: OK (3276 entries, 2121 classified, 1155 in the baseline of known-unclassified keys)
|
|
104
|
+
package: OK (793 files, @staix/agent-hub@0.31.0)
|
|
105
|
+
check: --changed found no affected tests
|
|
106
|
+
check: OK (changed)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Typecheck and bundle freshness also passed. This was a documentation-only
|
|
110
|
+
changed gate, not a new full runtime test run. The following documentation-only update
|
|
111
|
+
records that completed result; final-head checks and hosted CI are recorded on
|
|
112
|
+
the PR and remain the merge gate. No tag, consent, publication, installation or
|
|
113
|
+
live upgrade was performed.
|
|
114
|
+
|
|
115
|
+
## Reviews
|
|
116
|
+
|
|
117
|
+
Pull requests named by the commits since v0.30.0: #1216, #1211, #1214, #738, #1212, #1210, #1207, #1209, #1206, #1205, #1202, #1201, #1192, #1200, #1197, #1195, #1194, #1189, #1191, #1190, #1186, #1183, #1188, #1181, #1185, #1187, #1184, #1182, #1170, #1169, #1168, #1167, #1166, #1165.
|
|
118
|
+
|
|
119
|
+
`#738` in that list is hub task 738 named in #1212's subject, not a pull request of this range.
|
|
120
|
+
|
|
121
|
+
Each of the 33 merged at the head its hub task approved, read from the board (`ahub board --json`: `approval.head` equals the task's `refs.commit` and the PR's head, `mismatch: false`), with that head's CI green on ubuntu and macOS (18 to 21 checks pass, 2 skipped, none failing). Approvals by claude unless named:
|
|
122
|
+
|
|
123
|
+
- #1165 (task 695) at 5d1c984e; #1166 (696) at 71f1e1f0; #1167 (693) at ca882f2b; #1168 (694) at 59f352da; #1169 (697) at e5500129; #1170 (700) at 884036ba; #1181 (708) at 0b9fbe07; #1182 (715) at 56521a35; #1183 (702) at 56f1e7c5; #1184 (710) at 97bfcba4; #1185 (703) at c762d8a7; #1186 (704) at 96703ec9; #1187 (711) at 9e2b2719; #1188 (716) at 72958d19; #1189 (712) at 054cc353; #1190 (724) at 1ecdeb32; #1191 (717) at db519b67; #1192 (722) at dd5e87ff; #1195 (705) at 61168f74; #1197 (723) at 680f3c1f; #1200 (727) at a6c886bb; #1201 (718) at 96d01a2d; #1202 (725) at e0a5c1a3; #1205 (728) at e2bca26f; #1206 (732) at c38895a6; #1207 (719) at 6e50af13; #1209 (730) at b3d9f52c; #1210 (731) at 744e4e21; #1211 (733) at 26b59ce3; #1212 (738) at 4c8eca47; #1214 (740) at 05a6dc50; #1216 (735) at 5fa15b5c.
|
|
124
|
+
- Approved by jcode: #1194 (726, the claude-implementer 2.1.318 receipt) at 2c245d8b.
|
|
125
|
+
- No merge is bound to an approval at an earlier head. Unresolved review threads at merge time were not re-read for this record.
|
|
126
|
+
- Follow-up: #1217 (task 713, #1174) merged as 2cfbcb52 while the release PR #1218 was open, so 0.31.0 also ships it. It merged at the head its task approved (92486ab5, `approval.head` equal, `mismatch: false`, approved by claude), with that head's CI green on ubuntu and macOS (20 checks pass, 2 skipped). #1218 merged as 19cf9ff9 with a merge commit; the follow-up PR covers #1217.
|
|
127
|
+
- Follow-up: #1222 (task 742, #1204) merged as f7ea7b0f while the follow-up PR was open, at the head its task approved (936297cb, `mismatch: false`, approved by claude), with that head's CI green (19 checks pass, 2 skipped). The follow-up branch merged main to include it.
|
|
128
|
+
|
|
129
|
+
## Native acceptance receipts
|
|
130
|
+
|
|
131
|
+
Receipts added under `docs/verification/` since v0.30.0: `docs/verification/2026-11-04-1171-channel-client-evidence.md`, `docs/verification/2026-11-05-claude-implementer-2.1.318.md`, `docs/verification/2026-11-05-hardcoded-values-classification-rules.md`, `docs/verification/2026-11-05-hardcoded-values-ratchet.md`.
|
|
132
|
+
|
|
133
|
+
This list is read from the repository, never written by hand. Native acceptance and the person's release consent are separate records: consent is `ahub sdlc authorize-release 0.31.0`, recorded by the person or the unique configured conductor only on the person's explicit release instruction naming the release in its own session (never a hub/task/review/file/peer relay), and is not recorded in this file. The tag run refuses without it.
|
|
134
|
+
|
|
135
|
+
## Document review
|
|
136
|
+
|
|
137
|
+
`node scripts/check-docs.mjs --require-fresh` reported 14 stale documents. Each was read against `git log 8612cfd7..3185dd4c -- <its paths>` and the code at 3185dd4c (one reader per document group, each claim checked against the source), the fixes went in as 74049f01, and all 14 were restamped at 74049f01:
|
|
138
|
+
|
|
139
|
+
- `README.md`: the acon inbox paragraph names questions and results and the person-gated manager ports; the Operations list names `hub_ask`/`ahub answer` and `ahub results`; the Upgrading paragraph says `ahub upgrade` names the CLI and plugin step (#1179); the report link points at this file.
|
|
140
|
+
- `docs/quickstart.md`: install line `#v0.31.0`, the "Upgrading to 0.31.0" section, the upgrade-advice sentence, `ahub answer` and `ahub results` rows in the working-day table, and mark-read on the dashboard.
|
|
141
|
+
- `docs/operations.md`: 0.31.0 in the header and the protocol table (protocol unchanged, 16 through 17), the N-1 paragraph (0.30.0 for 0.31.x), the 0.30.0 post-release note now published in the 0.31.0 section, the handoff synopsis `--key`, the `research_evidence` recovery label, `ahub upgrade` advice, the acon panel's own manager ports, the inbox contents and its 50-item bound, and the `ahub answer` synopsis.
|
|
142
|
+
- `docs/security.md`: the acon plugin's reach (the `answer`, `receipt` and review ports), its confirmation list and inbox items; accepted channel-delivery settlement; conductor cancellation of handed-off tasks; the fourth handoff message, the key, sequence and `duplicate_ok` fields; dashboard question, result and review data; memory sync narrowing and `ahub memory declined`; `hub_evidence_record`; the 2.1.318 implementer receipt; the `liveTestRefusal` line; and a new "Anchored review comments (#1056)" section.
|
|
143
|
+
- `docs/agent-notes/adapters.md`: the `acceptedSettlement` port (#1172) and the owned input observers (#1056).
|
|
144
|
+
- `docs/agent-notes/budget.md`: transient `Bus.pause`/`resume` write no snapshot (#1214).
|
|
145
|
+
- `docs/agent-notes/bus.md`: pushed vs pulled answer parents, review-observer telemetry suppression, owner-audience reviews never moot, explicit-channel `accepted` resolution, accepted-delivery expiry, review provenance and room delivery rows.
|
|
146
|
+
- `docs/agent-notes/daemon.md`: the recovery floor list (`research_evidence`, `review_comments`, `review_observer_input_state`, `accepted_delivery_settlement`), the DOING privacy screens, review observer input, channel push evidence, the inbox project listing budget, held-hint rendering, memory sync policy outcomes and the retired pet window.
|
|
147
|
+
- `docs/agent-notes/local-worker.md`: the review-turn exclusion (#1181, #1192).
|
|
148
|
+
- `docs/agent-notes/tasks.md`: `Board.proposeHandoff`, `task_handoff_by_key`, sequence-ordered events and the periodic catch-up; claim evidence links; person review comments; long-term memory screening.
|
|
149
|
+
- `docs/agent-notes/tests.md`: time-bounded waits (#1163), the fake-ripwire probe (#1197), channel parent evidence in fixtures (#1171) and the published fixtures' retarget rule (#1168).
|
|
150
|
+
- No change needed: `src/cli/help.ts` (every form the 8 commits added matches `main.ts` and its parsers), `docs/agent-notes/README.md` and `docs/agent-notes/benchmarks.md` (each read; the commits in range do not change what they state).
|
|
151
|
+
- Not acted on, outside the stale set: AGENTS.md "Area notes" does not yet name the new files `src/hub/review-comments.ts`, `review-anchor.ts`, `review-material.ts`, `research-evidence.ts`, `memory-sync-policy.ts`, `question-detach.ts`, `completion-detail.ts`, `memory-sync-state.ts`, `src/ui/plugin-questions.ts` and the new `src/cli/*-args.ts` parsers; `test/specs-tasks.test.ts` and `test/broker-server.test.ts` still bound a wait by event-loop turns.
|
|
152
|
+
|
|
153
|
+
- Follow-up review of #1217: after #1218 merged, `check-docs --require-fresh` on main reported 12 documents stale by #1217 (and the #1218 merge). Each was re-read against #1217's diff only, the fixes went in as 142c80c7, and all 12 were restamped at 142c80c7:
|
|
154
|
+
- `README.md`: the Operations list names `ahub peer takeover`.
|
|
155
|
+
- `docs/operations.md`: the newest-hello sentence now applies only to a session that does not opt in to standby.
|
|
156
|
+
- `docs/security.md`: a paragraph on person-only takeover, standby fencing and display-only ids and PIDs.
|
|
157
|
+
- `docs/agent-notes/adapters.md`: the retained standby port (`retainStandby`, `takeover`, `ownsSocket`, closes 4405 and 4403).
|
|
158
|
+
- `docs/agent-notes/daemon.md`: the `peer_takeover` control message and detached-connection rule.
|
|
159
|
+
- `docs/agent-notes/tests.md`: close the fixture owner before attaching a second opted-in session.
|
|
160
|
+
- `src/cli/help.ts`: `ahub peer takeover` lists the `--json` and `--color` flags `main.ts` accepts.
|
|
161
|
+
- No change needed: `docs/agent-notes/README.md` (the `o` key acts on the selected row's displayed standby id, within the exact-row rule), `budget.md`, `bus.md`, `tasks.md` (#1217 changes no pause, queue or task path) and `docs/quickstart.md`.
|
|
162
|
+
- CHANGELOG: a #1217 entry under 0.31.0, and the N-1 statement names `peer_takeover`, `ahub peer takeover` and the standby opt-in in both directions.
|
|
163
|
+
- Follow-up review of #1222: the merge of main left 9 documents stale by its `src/hub/bus.ts` and `src/rooms/link.ts` changes. Each was re-read against #1222's diff, the one fix went in as aceed883, and all 9 were restamped there:
|
|
164
|
+
- `docs/agent-notes/bus.md`: a closed `Bus` publishes nothing and touches no journal or observer.
|
|
165
|
+
- No change needed: `README.md`, `docs/operations.md`, `docs/security.md`, `docs/quickstart.md`, `budget.md`, `daemon.md`, `tasks.md`, `tests.md` (their presence and queue statements still hold; #1222 changes no surface, setting or wire field).
|
|
166
|
+
- CHANGELOG: a #1222 entry under 0.31.0; it changes no N-1 surface.
|
|
167
|
+
|
|
168
|
+
## Checks
|
|
169
|
+
|
|
170
|
+
- `node scripts/check-docs.mjs --require-fresh`: `docs: OK (0 stale documents)` after the restamp at 74049f01.
|
|
171
|
+
- `scripts/check.sh --changed origin/main` on dgx02 (`remote_dev.py verify`) at e8f3a694 (tree a0576a8b) selected the full suite: `docs: OK (0 stale documents)`, `roles: OK`, `inventory: OK` (3267 entries, 1155 in the baseline), typecheck (`bun x tsc --noEmit`), the bundle check (`bun scripts/build.mjs --check`), `package: OK (791 files, @staix/agent-hub@0.31.0)`, and 11891 pass, 101 skip, 0 fail across 916 files with Bun 1.4.2; no daemon leaks; `check: OK`. It includes the published-runtime interoperability tests in both directions against 0.30.0 (release N-1) and 0.25.0 (protocol floor). Later commits on the release branch change only this report.
|
|
172
|
+
- The release PR's exact-head CI on ubuntu and macOS is the gate for the merge.
|
|
173
|
+
- Follow-up for #1217: `node scripts/check-docs.mjs --require-fresh` is `docs: OK (0 stale documents)` after the restamp at 142c80c7. `scripts/check.sh --changed origin/main` on dgx02 at 1acb9645 (tree e1a307e0) ran typecheck, the bundle check, `inventory: OK`, `package: OK (791 files, @staix/agent-hub@0.31.0)` and the 25 test files the change touches: 347 pass, 0 fail; `check: OK (changed)`. #1217's own full-suite and hosted CI receipts are in its PR. After that gate the branch merged main for #1222 (its own full dgx02 gate and hosted CI are in #1222) and added only documents, stamps and CHANGELOG lines; `check-docs --require-fresh` is clean at the final head. The follow-up PR's exact-head CI gates its merge, which must also be a merge commit.
|
|
174
|
+
|
|
175
|
+
## Known gaps, not blocking
|
|
176
|
+
|
|
177
|
+
- No installation, running-hub upgrade to 0.31.0 or live TUI launch was done for this record.
|
|
178
|
+
- #1053: AC1 live receipts and the T1 timeout measurement stay open; the per-adapter `hub_ask` waits are provisional.
|
|
179
|
+
- #1056 and #1204 (T3, T4) stay open; #1196 stays open until the person measures the live acon console.
|
|
180
|
+
- #1173: complete bounded declined listings are available. Automatic v3 sync still lacks the supported activation and fresh host-attestation path in agent-mem#281.
|
|
181
|
+
- #1184: the channel-evidence fallback reads the direct parent's process row; it is not authentication, and a published client opt-in is the upgrade path.
|
|
182
|
+
- The N-1 fixture lock remains the Bun 1.4.2 lock for 0.30.0. Prior published-runtime interoperability evidence is recorded above; this documentation-only completion adds no new full-runtime claim.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Claude Code 2.1.318 headless implementer receipt
|
|
2
|
+
|
|
3
|
+
Date: 2026-11-05. Scope: #888 (claude-implementer row). This repeats the procedures of the [2.1.316 receipt](2026-10-31-claude-implementer-2.1.316.md) on the installed Claude Code 2.1.318, with 2.1.316 run through the same producers as the control: the permission transport (Write, production-name Bash, Bash `updatedInput` rewrite) and the host shell wrapper. Source head: `801c6453`. Platform: macOS arm64, host Bun 1.4.3.
|
|
4
|
+
|
|
5
|
+
Result: every case passed on both binaries. `2.1.318` is added to `COMPAT["claude-implementer"].verified`. 2.1.317 is installed but was not run and is not verified by this receipt.
|
|
6
|
+
|
|
7
|
+
| Native version | Binary SHA-256 |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| Claude Code 2.1.316 (control) | `64c327e92b2c5e0f78c0a980c5a518121e1f0d140ca771ca5dd4488d1a2dcb3f` |
|
|
10
|
+
| Claude Code 2.1.318 | `677a2ea7bf576cedd20e191d973914ed8a41796f53a63b1923381ddc4d5b5e7d` |
|
|
11
|
+
|
|
12
|
+
The 2.1.316 hash matches the 2.1.316 receipt, so the control is the binary it certified.
|
|
13
|
+
|
|
14
|
+
## Upstream changes since 2.1.316
|
|
15
|
+
|
|
16
|
+
Read from the upstream [CHANGELOG](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) entries for 2.1.317 and 2.1.318. Items that touch permissions, MCP, hooks, settings sources, process lifetime or the Bash tool:
|
|
17
|
+
|
|
18
|
+
- **2.1.317, a check that asks before a web or shell tool call sends the account email address to the network**: a new ask. It fires only when a command carries the signed-in account's email; the model-free runs have no account, so this receipt does not exercise it. A real-account run that triggers it goes through the same permission prompt tool as any other ask.
|
|
19
|
+
- **2.1.317, child processes of a stopped shell command sent SIGTERM twice**: fixed. The producers still require every native child's process group to be empty afterwards; this tightens cleanup and loosens nothing.
|
|
20
|
+
- **2.1.317, edits to settings files in the first second after launch not taking effect** and **old transcripts not cleaned up for runs using `--setting-sources`**: fixed. The hub passes `--settings` with permission rules only before launch and an isolated `CLAUDE_CONFIG_DIR`, so neither changes the child's settings or permission inputs.
|
|
21
|
+
- **2.1.317, `claude -p` exiting 0 when a full disk lost its transcript or `~/.claude.json` writes**: it now exits 1. That makes a storage failure visible as a failed turn, not a silent success.
|
|
22
|
+
- **2.1.317, `claude -p` inside a cloud or self-hosted runner session sharing that session's ID** (`CLAUDE_CODE_DISABLE_NESTED_SESSION_ID`): the hub's implementer child is not started inside a runner session and gets the hub-built environment.
|
|
23
|
+
- **2.1.318, stdio MCP servers that exit on the version probe re-probed on every start; a server that dies in under 3s is pinned to the legacy handshake for 7 days**: the implementer child's MCP server (`--strict-mcp-config`, the hub permission server) does not exit on the probe; the transport runs below still negotiate and answer on 2.1.318.
|
|
24
|
+
- **2.1.318, a message sent right after a model change still running after Stop in headless sessions**: Stop now cancels it. The hub does not change models mid-turn in the implementer child.
|
|
25
|
+
- **2.1.318, MCP tool errors**: a call made before the tool is loaded now returns its input schema. This changes error text only; the permission tool is loaded before the first tool call in every run below.
|
|
26
|
+
- **2.1.318, unattended runs no longer rewrite `~/.claude.json` when nothing changed**, and a non-valid `~/.claude.json` now fails the start: the child runs with an isolated HOME and a fresh config.
|
|
27
|
+
- **2.1.318, git commits and PR creation when the Bash tool runs macOS's `/bin/bash`**: reliability only; the wrapper's persistent-cwd control below still passes.
|
|
28
|
+
|
|
29
|
+
Nothing in these entries changes `--permission-prompts host`, `--permission-prompt-tool`, `--strict-mcp-config`, `--setting-sources` or the `updatedInput` reply contract. This reading is of the changelog text, not the binary's source, which is not public.
|
|
30
|
+
|
|
31
|
+
## Runs
|
|
32
|
+
|
|
33
|
+
Each producer ran both binaries sequentially with an isolated HOME and `CLAUDE_CONFIG_DIR`, a fixture MCP server, a deterministic loopback provider and the literal API key `synthetic-probe-not-a-credential`. No account, provider request or model inference was involved. Every native child's process group was confirmed empty afterwards and every binary hash was unchanged.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
python3 docs/verification/claude-permission-transport-native.py OUT/write --claude 2.1.316 --claude 2.1.318
|
|
37
|
+
python3 docs/verification/claude-permission-transport-native.py OUT/bash --tool Bash --server-name agent-hub --permission-tool hub_permission_request --require-tool-use-id --claude ... --claude ...
|
|
38
|
+
python3 docs/verification/claude-permission-transport-native.py OUT/rewrite --tool Bash --rewrite-bash --server-name agent-hub --permission-tool hub_permission_request --require-tool-use-id --claude ... --claude ...
|
|
39
|
+
python3 docs/verification/claude-shell-wrapper-native.py OUT/wrapper --bun ABSOLUTE_BUN --claude ... --claude ...
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
(binary arguments are the absolute installed paths; `--bun` was the Homebrew Bun 1.4.3 path resolved with `readlink -f`, since `command -v bun` names a shell function in an interactive zsh).
|
|
43
|
+
|
|
44
|
+
| Producer | Cases per binary | 2.1.316 | 2.1.318 |
|
|
45
|
+
| --- | --- | --- | --- |
|
|
46
|
+
| Write transport (allow, deny, missing tool, hook deny/allow, MCP error, disconnect, pending, deadline) | 9 | 9 pass | 9 pass |
|
|
47
|
+
| Bash transport, production server and tool names, `tool_use_id` required | 9 | 9 pass | 9 pass |
|
|
48
|
+
| Bash `updatedInput` command replacement (allow, deny) | 2 | 2 pass | 2 pass |
|
|
49
|
+
| Host shell wrapper (persistent-cwd control, fixed-wrapper rewrite with replay refusal) | 2 | 2 pass | 2 pass |
|
|
50
|
+
|
|
51
|
+
Per-case shapes on 2.1.318 match the control: pending stopped externally at the deadline; wrapper control 3 requests and 2 permission calls, wrapper rewrite 4 requests and 3 permission calls with the effect counter at exactly 1 after replay.
|
|
52
|
+
|
|
53
|
+
The only producer change is the version allow-list in `claude-shell-wrapper-native.py`, which now admits `2.1.318`.
|
|
54
|
+
|
|
55
|
+
| Artifact | SHA-256 |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| Permission producer (unchanged) | `8f8885f7153b3a236f3b3f8ce49a344b908f2af3b3aba8b064762d82d1ecf12a` |
|
|
58
|
+
| Wrapper producer (this change) | `af61fcd08df7da42708226d73949646581d4b9d66d5c243de2c9d2c80afccb23` |
|
|
59
|
+
| Wrapper host fixture (unchanged) | `616e6711e392f0eee7e3fa1c7bdc47a537dfa86bcc8ffb30e549ca94e5a71cef` |
|
|
60
|
+
| Fixed CLI wrapper (unchanged) | `8ff56514a6e3f25bce0784775d396df199b58b1b93f55ad0e8747bbc729d2fd8` |
|
|
61
|
+
| Write receipt JSON | `c0977198860c5a5141f7d49e8a52616aa4556b406975de8adb25f3ef1d0dbc52` |
|
|
62
|
+
| Bash receipt JSON | `14a44372f3b44b32956aecd37e50836fb39f9a2847ad7b33e6185fb9784fac55` |
|
|
63
|
+
| Rewrite receipt JSON | `ee3d66252006581a0481fe326313b674b1437d27b9adc8e617690c0efc45d3af` |
|
|
64
|
+
| Wrapper receipt JSON | `2996280113526fd41a005a510656f47c0f20d4dba46d11611191238ed9576a4f` |
|
|
65
|
+
|
|
66
|
+
The receipt JSON files stay in the local diagnostic directory; they carry local paths and are not committed.
|
|
67
|
+
|
|
68
|
+
## Evidence boundaries
|
|
69
|
+
|
|
70
|
+
Unchanged from the earlier receipts: no real provider authentication, model tool selection, person approval interaction, task-session resume or production-daemon task binding is proved, and this is not a runtime receipt gate. The 2.1.317 account-email ask is not exercised (no account). Native version admission and binary fencing remain required. The Monitor tool is still an unrewritten prompt-tool path. Exact-head package gate and CI are recorded on the PR.
|