@staix/agent-hub 0.27.0 → 0.29.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 +33 -0
- package/README.md +11 -3
- package/docs/agent-notes/adapters.md +4 -2
- package/docs/agent-notes/bus.md +4 -4
- package/docs/agent-notes/daemon.md +9 -3
- package/docs/agent-notes/local-worker.md +3 -1
- package/docs/agent-notes/tasks.md +7 -0
- package/docs/agent-notes/tests.md +7 -5
- package/docs/design/adapters.md +76 -0
- package/docs/design/agent-hub-architecture.md +67 -0
- package/docs/design/agent-hub.md +52 -0
- package/docs/design/bus.md +48 -0
- package/docs/design/task-board.md +86 -0
- package/docs/dogfood.md +21 -3
- package/docs/operations.md +370 -12
- package/docs/profiles.md +1 -0
- package/docs/quickstart.md +19 -3
- package/docs/sdlc.md +2 -2
- package/docs/security.md +24 -4
- package/docs/smoke.md +2 -0
- package/docs/specs/2026-09-19-agent-hub-design.md +2 -0
- package/docs/verification/2026-10-31-codex-0166-reviewer-isolation.md +2 -0
- package/docs/verification/2026-11-02-0.28.0.md +54 -0
- package/docs/verification/2026-11-02-autonomy-t4.md +39 -0
- package/docs/verification/2026-11-02-codex-0166-reviewer-tool-call.md +53 -0
- package/docs/verification/2026-11-02-control-write-after.json +139 -0
- package/docs/verification/2026-11-02-control-write-baseline.json +127 -0
- package/docs/verification/2026-11-02-control-write-guarded.json +127 -0
- package/docs/verification/2026-11-02-control-write-outcomes.md +65 -0
- package/docs/verification/2026-11-02-orca-1.4.245-cli-contract.md +51 -0
- package/docs/verification/2026-11-03-0.29.0.md +59 -0
- package/docs/verification/2026-11-03-control-write-stall-windows.json +241 -0
- package/docs/verification/2026-11-03-control-write-stall-windows.md +20 -0
- package/docs/verification/2026-11-03-live-board-latency.json +556 -0
- package/docs/verification/2026-11-03-live-board-latency.md +64 -0
- package/docs/verified.json +14 -14
- package/package.json +2 -2
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +857 -125
- package/src/adapters/claude-channel.ts +12 -2
- package/src/adapters/compat.ts +1 -1
- package/src/adapters/definitions/native-cli-claude-setup.ts +31 -9
- package/src/adapters/definitions/native-cli-entry-jcode.ts +33 -0
- package/src/adapters/definitions/native-cli-entry-qwen.ts +2 -2
- package/src/adapters/jcode.ts +37 -4
- package/src/adapters/qwen-dual.ts +3 -2
- package/src/cli/agents.ts +4 -2
- package/src/cli/bench.ts +4 -2
- package/src/cli/board-read.ts +25 -0
- package/src/cli/claude-homes.ts +2 -2
- package/src/cli/console-state.ts +8 -3
- package/src/cli/help.ts +6 -5
- package/src/cli/identity.ts +9 -1
- package/src/cli/init-prompt.ts +179 -0
- package/src/cli/init-settings.ts +229 -0
- package/src/cli/init.ts +102 -9
- package/src/cli/launch.ts +3 -1
- package/src/cli/main.ts +106 -35
- package/src/cli/output.ts +19 -0
- package/src/cli/recovery-package.ts +9 -0
- package/src/cli/setup-homes.ts +18 -3
- package/src/cli/specs.ts +150 -0
- package/src/cli/terminal-recovery.ts +35 -11
- package/src/hub/board.ts +59 -5
- package/src/hub/bus.ts +54 -7
- package/src/hub/child-process.ts +6 -4
- package/src/hub/config-apply.ts +4 -1
- package/src/hub/config-edit.ts +1 -1
- package/src/hub/config-tier.ts +1 -0
- package/src/hub/control-client.ts +43 -4
- package/src/hub/control-write-trace.ts +409 -0
- package/src/hub/cost-governance.ts +22 -6
- package/src/hub/crash.ts +20 -0
- package/src/hub/daemon.ts +470 -98
- package/src/hub/delivery-hints.ts +6 -3
- package/src/hub/delivery-journal.ts +14 -3
- package/src/hub/hub-tools.ts +10 -6
- package/src/hub/peers.ts +1 -1
- package/src/hub/review-brief.ts +18 -0
- package/src/hub/routing.ts +14 -3
- package/src/hub/runtime-capture-prune.ts +4 -1
- package/src/hub/sdlc-release-authorization.ts +13 -4
- package/src/hub/sdlc-release.ts +23 -10
- package/src/hub/sdlc.ts +15 -2
- package/src/hub/settings.ts +2 -0
- package/src/hub/specs-config.ts +43 -0
- package/src/hub/specs-task.ts +108 -0
- package/src/hub/specs.ts +1008 -0
- package/src/hub/task-list-page.ts +75 -0
- package/src/hub/task-sweep.ts +10 -1
- package/src/hub/task-worktree.ts +331 -0
- package/src/hub/tasks.ts +606 -53
- package/src/hub/terminal-open.ts +10 -5
- package/src/hub/tool-request.ts +131 -0
- package/src/local/deny.ts +49 -0
- package/src/local/tools.ts +4 -2
- package/src/memory/brief.ts +5 -0
- package/src/memory/client.ts +5 -2
- package/src/ui/office-model.ts +17 -1
- package/src/ui/office-space.ts +1 -1
- package/templates/config.json +1 -0
- package/templates/profiles/dev.json +1 -0
- package/templates/profiles/general.json +1 -0
- package/templates/profiles/research.json +1 -0
- package/templates/profiles/writing.json +1 -0
- package/templates/specs.block.md +5 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "agent-hub.control-write-latency/v1",
|
|
3
|
+
"ok": true,
|
|
4
|
+
"mode": "full",
|
|
5
|
+
"host": {
|
|
6
|
+
"platform": "linux",
|
|
7
|
+
"arch": "x64",
|
|
8
|
+
"bun": "1.4.2"
|
|
9
|
+
},
|
|
10
|
+
"fixture": {
|
|
11
|
+
"tasksSeeded": 600,
|
|
12
|
+
"taskHistoryNotes": 12,
|
|
13
|
+
"noteBytes": 4096,
|
|
14
|
+
"boardAfterSeed": {
|
|
15
|
+
"hubDb": 30617600,
|
|
16
|
+
"hubDbWal": 0
|
|
17
|
+
},
|
|
18
|
+
"boardAfterRun": {
|
|
19
|
+
"hubDb": 30859264,
|
|
20
|
+
"hubDbWal": 4140632
|
|
21
|
+
},
|
|
22
|
+
"events": {
|
|
23
|
+
"bytes": 110100480,
|
|
24
|
+
"rows": 215040,
|
|
25
|
+
"bytesAtEndOfSamples": 110322809
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"startup": {
|
|
29
|
+
"totalMs": 1106.66,
|
|
30
|
+
"includesStartupEventLogReads": true
|
|
31
|
+
},
|
|
32
|
+
"timing": "p50/p95 are ControlClient request round trips; Board method timings are nested synchronous observations and not additive",
|
|
33
|
+
"scope": {
|
|
34
|
+
"taskWrites": "ControlClient task RPCs",
|
|
35
|
+
"deliveryComplete": "real accepted delivery journal path using a synthetic peer ControlClient",
|
|
36
|
+
"channelMcpWrapper": "not measured",
|
|
37
|
+
"nativeModelsAndAccounts": "not used"
|
|
38
|
+
},
|
|
39
|
+
"iterationsPerPhase": 20,
|
|
40
|
+
"phases": [
|
|
41
|
+
{
|
|
42
|
+
"name": "review_approved",
|
|
43
|
+
"count": 20,
|
|
44
|
+
"p50Ms": 269.32,
|
|
45
|
+
"p95Ms": 326.65,
|
|
46
|
+
"outcomes": {
|
|
47
|
+
"ok": 20
|
|
48
|
+
},
|
|
49
|
+
"states": {
|
|
50
|
+
"approved": 20
|
|
51
|
+
},
|
|
52
|
+
"board": {
|
|
53
|
+
"listCalls": 180,
|
|
54
|
+
"listRows": 92300,
|
|
55
|
+
"listMs": 4857.6,
|
|
56
|
+
"taskWriteCalls": 20,
|
|
57
|
+
"taskWriteMs": 2394.95,
|
|
58
|
+
"deliveryCompleteCalls": 0,
|
|
59
|
+
"deliveryCompleteMs": 0
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "proposal_backlog",
|
|
64
|
+
"count": 20,
|
|
65
|
+
"p50Ms": 57.52,
|
|
66
|
+
"p95Ms": 69.66,
|
|
67
|
+
"outcomes": {
|
|
68
|
+
"ok": 20
|
|
69
|
+
},
|
|
70
|
+
"states": {
|
|
71
|
+
"backlog": 20
|
|
72
|
+
},
|
|
73
|
+
"board": {
|
|
74
|
+
"listCalls": 40,
|
|
75
|
+
"listRows": 21100,
|
|
76
|
+
"listMs": 1008.72,
|
|
77
|
+
"taskWriteCalls": 20,
|
|
78
|
+
"taskWriteMs": 1141.61,
|
|
79
|
+
"deliveryCompleteCalls": 0,
|
|
80
|
+
"deliveryCompleteMs": 0
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "proposal_claim",
|
|
85
|
+
"count": 20,
|
|
86
|
+
"p50Ms": 448,
|
|
87
|
+
"p95Ms": 486.09,
|
|
88
|
+
"outcomes": {
|
|
89
|
+
"ok": 20
|
|
90
|
+
},
|
|
91
|
+
"states": {
|
|
92
|
+
"in_progress": 20
|
|
93
|
+
},
|
|
94
|
+
"board": {
|
|
95
|
+
"listCalls": 260,
|
|
96
|
+
"listRows": 150340,
|
|
97
|
+
"listMs": 7292.79,
|
|
98
|
+
"taskWriteCalls": 60,
|
|
99
|
+
"taskWriteMs": 4500.39,
|
|
100
|
+
"deliveryCompleteCalls": 0,
|
|
101
|
+
"deliveryCompleteMs": 0
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "delivery_complete",
|
|
106
|
+
"count": 20,
|
|
107
|
+
"p50Ms": 7.33,
|
|
108
|
+
"p95Ms": 28.33,
|
|
109
|
+
"outcomes": {
|
|
110
|
+
"completed": 20
|
|
111
|
+
},
|
|
112
|
+
"states": {
|
|
113
|
+
"completed": 20
|
|
114
|
+
},
|
|
115
|
+
"board": {
|
|
116
|
+
"listCalls": 0,
|
|
117
|
+
"listRows": 0,
|
|
118
|
+
"listMs": 0,
|
|
119
|
+
"taskWriteCalls": 0,
|
|
120
|
+
"taskWriteMs": 0,
|
|
121
|
+
"deliveryCompleteCalls": 20,
|
|
122
|
+
"deliveryCompleteMs": 145.03
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"sourceCommit": "5e3a59a8168d61e6aff38027d86ef53a7283abb3"
|
|
127
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "agent-hub.control-write-latency/v1",
|
|
3
|
+
"ok": true,
|
|
4
|
+
"mode": "full",
|
|
5
|
+
"host": {
|
|
6
|
+
"platform": "linux",
|
|
7
|
+
"arch": "x64",
|
|
8
|
+
"bun": "1.4.2"
|
|
9
|
+
},
|
|
10
|
+
"fixture": {
|
|
11
|
+
"tasksSeeded": 600,
|
|
12
|
+
"taskHistoryNotes": 12,
|
|
13
|
+
"noteBytes": 4096,
|
|
14
|
+
"boardAfterSeed": {
|
|
15
|
+
"hubDb": 30617600,
|
|
16
|
+
"hubDbWal": 0
|
|
17
|
+
},
|
|
18
|
+
"boardAfterRun": {
|
|
19
|
+
"hubDb": 30859264,
|
|
20
|
+
"hubDbWal": 4148872
|
|
21
|
+
},
|
|
22
|
+
"events": {
|
|
23
|
+
"bytes": 110100480,
|
|
24
|
+
"rows": 215040,
|
|
25
|
+
"bytesAtEndOfSamples": 110322809
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"startup": {
|
|
29
|
+
"totalMs": 1191.02,
|
|
30
|
+
"includesStartupEventLogReads": true
|
|
31
|
+
},
|
|
32
|
+
"timing": "p50/p95 are ControlClient request round trips; Board method timings are nested synchronous observations and not additive",
|
|
33
|
+
"scope": {
|
|
34
|
+
"taskWrites": "ControlClient task RPCs",
|
|
35
|
+
"deliveryComplete": "real accepted delivery journal path using a synthetic peer ControlClient",
|
|
36
|
+
"channelMcpWrapper": "not measured",
|
|
37
|
+
"nativeModelsAndAccounts": "not used"
|
|
38
|
+
},
|
|
39
|
+
"iterationsPerPhase": 20,
|
|
40
|
+
"phases": [
|
|
41
|
+
{
|
|
42
|
+
"name": "review_approved",
|
|
43
|
+
"count": 20,
|
|
44
|
+
"p50Ms": 302.03,
|
|
45
|
+
"p95Ms": 368.5,
|
|
46
|
+
"outcomes": {
|
|
47
|
+
"ok": 20
|
|
48
|
+
},
|
|
49
|
+
"states": {
|
|
50
|
+
"approved": 20
|
|
51
|
+
},
|
|
52
|
+
"board": {
|
|
53
|
+
"listCalls": 180,
|
|
54
|
+
"listRows": 92300,
|
|
55
|
+
"listMs": 5524.54,
|
|
56
|
+
"taskWriteCalls": 20,
|
|
57
|
+
"taskWriteMs": 2687.48,
|
|
58
|
+
"deliveryCompleteCalls": 0,
|
|
59
|
+
"deliveryCompleteMs": 0
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "proposal_backlog",
|
|
64
|
+
"count": 20,
|
|
65
|
+
"p50Ms": 64.4,
|
|
66
|
+
"p95Ms": 76.47,
|
|
67
|
+
"outcomes": {
|
|
68
|
+
"ok": 20
|
|
69
|
+
},
|
|
70
|
+
"states": {
|
|
71
|
+
"backlog": 20
|
|
72
|
+
},
|
|
73
|
+
"board": {
|
|
74
|
+
"listCalls": 40,
|
|
75
|
+
"listRows": 21100,
|
|
76
|
+
"listMs": 1108.5,
|
|
77
|
+
"taskWriteCalls": 20,
|
|
78
|
+
"taskWriteMs": 1243.59,
|
|
79
|
+
"deliveryCompleteCalls": 0,
|
|
80
|
+
"deliveryCompleteMs": 0
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "proposal_claim",
|
|
85
|
+
"count": 20,
|
|
86
|
+
"p50Ms": 596.16,
|
|
87
|
+
"p95Ms": 634.64,
|
|
88
|
+
"outcomes": {
|
|
89
|
+
"ok": 20
|
|
90
|
+
},
|
|
91
|
+
"states": {
|
|
92
|
+
"in_progress": 20
|
|
93
|
+
},
|
|
94
|
+
"board": {
|
|
95
|
+
"listCalls": 320,
|
|
96
|
+
"listRows": 187560,
|
|
97
|
+
"listMs": 10216.67,
|
|
98
|
+
"taskWriteCalls": 60,
|
|
99
|
+
"taskWriteMs": 5184.14,
|
|
100
|
+
"deliveryCompleteCalls": 0,
|
|
101
|
+
"deliveryCompleteMs": 0
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "delivery_complete",
|
|
106
|
+
"count": 20,
|
|
107
|
+
"p50Ms": 9.82,
|
|
108
|
+
"p95Ms": 33.77,
|
|
109
|
+
"outcomes": {
|
|
110
|
+
"completed": 20
|
|
111
|
+
},
|
|
112
|
+
"states": {
|
|
113
|
+
"completed": 20
|
|
114
|
+
},
|
|
115
|
+
"board": {
|
|
116
|
+
"listCalls": 0,
|
|
117
|
+
"listRows": 0,
|
|
118
|
+
"listMs": 0,
|
|
119
|
+
"taskWriteCalls": 0,
|
|
120
|
+
"taskWriteMs": 0,
|
|
121
|
+
"deliveryCompleteCalls": 20,
|
|
122
|
+
"deliveryCompleteMs": 148.22
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"sourceCommit": "7615b065fcc5a6c0f9e0fd78fa4daed1531b4f5a"
|
|
127
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Control write outcomes and latency, 2026-11-02
|
|
2
|
+
|
|
3
|
+
Refs #1078, task #631.
|
|
4
|
+
|
|
5
|
+
## Pre-change measurement
|
|
6
|
+
|
|
7
|
+
Source plus fixture commit: `5e3a59a8168d61e6aff38027d86ef53a7283abb3`, based on main `8511d01a`.
|
|
8
|
+
Run: dgx02 `remote_dev.py verify`, pinned Bun 1.4.2, linux/x64; exit 0 in 25 seconds.
|
|
9
|
+
Command: `bun install --frozen-lockfile && bun scripts/benchmarks/control-write-latency.ts`.
|
|
10
|
+
|
|
11
|
+
The isolated fixture seeded 600 tasks, 12 history notes of 4096 bytes per task, a 30,617,600-byte database and a 110,100,480-byte (105 MiB) event log with 215,040 synthetic rows. Startup, including event-log reads, took 1106.66 ms and is excluded from write round trips. There were 20 samples per phase, all successful; p95 is the nearest-rank 19th sample. The host is shared; this is not a dedicated-host or cross-platform performance guarantee.
|
|
12
|
+
|
|
13
|
+
| Operation | Samples | p50 ms | p95 ms | Board.list calls | Rows decoded |
|
|
14
|
+
| --- | --- | --- | --- | --- | --- |
|
|
15
|
+
| review_approved | 20 | 269.32 | 326.65 | 180 | 92300 |
|
|
16
|
+
| proposal_backlog | 20 | 57.52 | 69.66 | 40 | 21100 |
|
|
17
|
+
| proposal_claim | 20 | 448 | 486.09 | 260 | 150340 |
|
|
18
|
+
| delivery_complete | 20 | 7.33 | 28.33 | 0 | 0 |
|
|
19
|
+
|
|
20
|
+
Measurements are actual ControlClient request round trips through production startDaemon/Tasks/Bus, not the MCP stdio wrapper. Board timings observe nested synchronous methods, so their durations must not be added to write durations. The completed-delivery phase uses an accepted journaled delivery from a synthetic peer. HOME and agent homes are private fixtures; inference, memory and MLX are disabled, PII screening is scripted clear, and no native agent, account or model is called. No real hub board or person configuration is modified.
|
|
21
|
+
|
|
22
|
+
Aggregate machine receipt: [baseline JSON](2026-11-02-control-write-baseline.json), SHA-256 `d967281b6d5e28bb42dc7a6dae0edd986834763fab151842f960db21def6906b`. It contains counts and timing metadata only.
|
|
23
|
+
|
|
24
|
+
## What the measurement establishes
|
|
25
|
+
|
|
26
|
+
The 35-45 second production symptom is not reproduced by this database/log-size fixture: all four measured p95 values are below 0.5 seconds before behavior changes. Repeated full Board.list decoding is a measurable cost (9 scans per review and 13 per claimed proposal), but this does not establish it as the cause of the reported production stalls. The measured completed-delivery path performs no Board.list calls. External/model-screen waits and the channel MCP wrapper are not measured here; no timeout is widened and no speculative Board cache is added on this evidence.
|
|
27
|
+
|
|
28
|
+
## Measured privacy-read hot path
|
|
29
|
+
|
|
30
|
+
The first guarded implementation at `7615b065fcc5a6c0f9e0fd78fa4daed1531b4f5a` exposed three additional full Board.list scans per claimed proposal: 320 calls over 20 samples, versus 260 before the change, with claim p95 634.64 ms. The [intermediate receipt](2026-11-02-control-write-guarded.json) is retained rather than overwritten.
|
|
31
|
+
|
|
32
|
+
The privacy predicate needs only state and signal flags for tasks owned or reviewed by that peer. A fresh Board.peerTaskSignals query now reads just those fields, without decoding unrelated titles, plans or histories. The daemon retains the same `isClosedTaskState` and `Tasks.isPii` predicates, including the current routing policy; no privacy result is cached. Corrupt required signal data fails closed, while unrelated history bytes are not a privacy input. The benchmark separately counts these fresh projections.
|
|
33
|
+
|
|
34
|
+
## Post-projection measurement
|
|
35
|
+
|
|
36
|
+
Source snapshot `2adfd6bd0e108baec09b9c75e937b162ff6e316c` used the same 600-task/12-note/105 MiB fixture and 20 samples per operation. All 80 operations succeeded. The aggregate [post-change receipt](2026-11-02-control-write-after.json) has SHA-256 `44e932568954c387d9a278f4c3bc5c1d0cb01e23dda4550981db8db17afcaa0e`. It measures the source snapshot, independently of later invalid-input-only compatibility checks and documentation commits.
|
|
37
|
+
|
|
38
|
+
| Operation | p50 ms | p95 ms | Full Board.list calls | Fresh signal projections | Projection ms (total) |
|
|
39
|
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
40
|
+
| review_approved | 247.64 | 301.97 | 140 | 40 | 7.28 |
|
|
41
|
+
| proposal_backlog | 60.86 | 75.6 | 40 | 0 | 0 |
|
|
42
|
+
| proposal_claim | 473.43 | 529.83 | 260 | 60 | 9.21 |
|
|
43
|
+
| delivery_complete | 8.89 | 26.97 | 0 | 0 | 0 |
|
|
44
|
+
|
|
45
|
+
Claim full scans returned from 320 in the first guarded version to 260, with all 60 new privacy projections still executed. Those projections took 9.21 ms total across 20 claims; they are fresh reads rather than cached decisions. Review full scans fell from 180 to 140. Shared-host timing variation prevents a general speedup claim; the measured p95 values and scan counts are reported without discarding the intermediate run. The reported live 35-45 second delay remains unverified.
|
|
46
|
+
|
|
47
|
+
## Implementation and verification
|
|
48
|
+
|
|
49
|
+
The bounded replay registry over the authenticated control connection applies to `hub_task_propose` and `hub_review`; `hub_delivery_done` uses the delivery journal's existing idempotency. The control message carries `requestId` separately from transport `rid`; duplicate calls keep their own transport correlation while joining one pending write or returning its first retained result. A changed actor/role/launch/execution scope or changed arguments cannot reuse that ID. Current authority/privacy gates still run before results leave the daemon. Deterministic read-only, capability and reviewer denials use the original pre-effect validation and retain their specific error/isError behavior. Malformed review identifiers reach the strict task validator before authority coercion. Invocation retains its existing admission/cancellation protocol.
|
|
50
|
+
|
|
51
|
+
The additive `tool_write_idempotency` feature enables automatic request IDs in current clients. Legacy calls without IDs retain their execution behavior. A client never resubmits an explicit replay to a legacy daemon that would ignore its ID. Timeout, cancellation after sending and socket loss report an unknown outcome, name a settling read (`hub_task_list`, `hub_task_show`, or the person's/conductor's `ahub queue show`), and do not automatically retry. The channel keeps unknown outcomes out of the generic `isError` retry path.
|
|
52
|
+
|
|
53
|
+
The daemon retains up to 512 keys per authenticated actor and 64 KiB per result within a 15-minute replay window. Actor capacity is shared across that actor's operations/generations, not across other actors. In-flight keys never expire into a second execution. Expired or different-instance IDs are refused without reapplying; a monotonic wall-clock watermark prevents a backwards clock jump from reviving an expired ID. Capacity refuses new writes rather than evicting a live key. Unexpected failures or oversized results retain a bounded unknown receipt, not a second effect. This is an in-memory, per-daemon contract, not a durable cross-restart result ledger; a prior instance's ID is refused after restart and is never applied by a current supporting daemon.
|
|
54
|
+
|
|
55
|
+
Cached overlap metadata is also bound to the current visibility of its referenced tasks. Up to 64 unique formatted overlap references are checked with fresh id/signals-only queries, including completed tasks; private, missing or ambiguous references withhold the cached text without another effect. The regression first failed with a real cached path after only the other owner's task became PII, then passed with the referenced-task guard.
|
|
56
|
+
|
|
57
|
+
The reviewed revision replaces the original MCP JSON-RPC-ID map with explicit optional `request_id` arguments. Unknown responses echo the key; a retry with a fresh JSON-RPC ID forwards that same control key and excludes it from the business payload. Delivery acknowledgement now uses only the existing idempotent journal path and consumes no registry capacity. Preadmission validation, authority and capacity refusals are definite `outcome: refused` for the current attempt; uncertainty remains for sent or potentially applied writes. These revisions address F-channel-key-jsonrpc-id and F-replay-cap-global; historical timing receipts above keep their original source snapshots and are not relabeled as new measurements.
|
|
58
|
+
|
|
59
|
+
Helper/client focused verification at `bd7f723444595b94e7f2b8176417c6a5f0a87871` passed 27 tests and typecheck on dgx02. Integrated focused verification at `7615b065fcc5a6c0f9e0fd78fa4daed1531b4f5a` passed 65 tests and typecheck; projection verification at `2adfd6bd0e108baec09b9c75e937b162ff6e316c` passed 66 tests across eight files, typecheck and a byte-identical pinned bundle rebuild. Final focused verification at `e3bee9ac94d9cd0c9910dfd4639c4f245c18753d` passed 69 tests, 550 assertions across eight files, typecheck and bundle freshness. It includes preserving uncertainty metadata through the last authority reply fence, while legacy replies stay unchanged. Final changed-gate results and hosted CI state are recorded against the exact reviewed head in the PR and task #631.
|
|
60
|
+
|
|
61
|
+
The first full changed-gate attempt at `3dd0a0480db4ca0d768184afec30f2a5c79f8faa` was stopped by the implementer (exit 130 after 698 seconds), not passed. It exposed 24 compatibility failures: static recovery metadata could not parse a computed feature entry, known permission denials had become unknown information responses, and a VM fixture lacked the new peer-signal read port. The production literal declaration and known-refusal path were corrected; the existing fixture gained its required port with no assertion weakened. The cached-overlap PII issue was separately reproduced before its fix. Targeted verification at the subsequent source snapshot passed 94 tests, 849 assertions across ten files and typecheck, including the original failing contracts. The final full-gate outcome remains bound to the PR/task head rather than inferred from this earlier attempt.
|
|
62
|
+
|
|
63
|
+
The complete rebased run at `3b81210c2388502f8825c072fc509a13633efcfa` finished with 10,800 pass, 85 skip and one failure across 835 files (299,227 assertions, 1,548.80 seconds of tests; invocation exit 1 after 1,610 seconds). No current-invocation daemon leak was found. The sole failure was the native-predicate architecture ratchet: the new toolWriteScope had added one isWsPeer call. The correction reuses the existing generic connectionGeneration helper; the baseline is unchanged. Exact-head correction-gate output and hosted CI remain separate evidence in the PR/task record.
|
|
64
|
+
|
|
65
|
+
The post-approval rebase preserves main's queue-discard and recovery-hold changes. Proposal privacy admission remains turn-scoped (`piiTurn` or the actor's private turn), rather than refusing solely because the actor owns another open PII task. Current task/overlap privacy still protects cached receipts. Delivery completion exposes only its journal identity (delivery ID and generation); the unused MCP `request_id` schema and forwarding are removed. Task proposal/review retry keys are unchanged.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Orca CLI contract recheck on 1.4.245
|
|
2
|
+
|
|
3
|
+
- Issue: #1090; hub task #643.
|
|
4
|
+
- Date: 2026-11-02, Asia/Seoul.
|
|
5
|
+
- Orca: `orca --version` printed `1.4.245`. The earlier observations in `src/cli/terminal-recovery.ts` were made on 1.4.223.
|
|
6
|
+
- Result: every command and error code agent-hub depends on for reading is **observed** on 1.4.245 and matches what the code expects. The commands that create, close or switch a pane are **unverified**, on purpose: this probe never creates, switches, closes or writes to a live pane.
|
|
7
|
+
|
|
8
|
+
## How this was checked
|
|
9
|
+
|
|
10
|
+
Read-only commands only, against the person's running Orca, from a script that printed field names, types, counts and error codes, never a value: `orca --version`, `orca terminal list --json`, `orca terminal show --terminal <handle> --json`, `orca terminal wait --terminal <handle> --for tui-idle --timeout-ms 1 --json`, `orca worktree current --json`, `orca worktree list --json`, and `--help` for the command groups. A `wait` returns at once when the terminal is already idle and otherwise times out after the 1 ms given, so it changes no pane. The error cases used a made-up handle that no terminal has, and a temporary directory Orca does not manage. No terminal handle, tab id, leaf id, worktree id, host name or path is recorded here, and nothing in this receipt can be used to find a pane.
|
|
11
|
+
|
|
12
|
+
## Commands the code reads, and what 1.4.245 does
|
|
13
|
+
|
|
14
|
+
| Command (as `terminal-recovery.ts` runs it) | Observed on 1.4.245 | What the code needs |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `terminal list --json` | exit 0, `ok: true`. `result` holds `terminals` (a list), `totalCount`, `truncated`, `hostScope` and `topologyRevisions`. A row holds `handle`, `incarnationId`, `worktreeId`, `worktreePath`, `agentIdentity`, `orphaned`, `writable`, `connected`, `title`, `preview`, `tabId`, `leafId`, `ptyId`, `branch`, `executionHostId` and `lastOutputAt`. `truncated` was `false` and `totalCount` equalled the row count. Every row had a non-empty `handle` and `incarnationId`, and both were unique across the list. | `listTerminals` reads `result.terminals` (or `result.items`). The complete-inventory check refuses a `truncated: true` list, a non-list, a row without a full identity, and a repeated handle or incarnation. |
|
|
17
|
+
| `terminal show --terminal <handle> --json` | exit 0, `ok: true`. `result.terminal` holds the same identity fields as a list row plus `agentWait`, `paneRuntimeId` and `rendererGraphEpoch`. Its `handle`, `incarnationId` and `worktreeId` equalled the list row's. | `terminalObject` unwraps `result.terminal`. `verifyBindingData` compares `handle`, `incarnationId`, `worktreeId` and the root. |
|
|
18
|
+
| `terminal wait --terminal <handle> --for tui-idle --timeout-ms <n> --json` | On a terminal that was already idle: exit 0 and `result.wait`. On one that was not idle within the timeout: exit 1 with `{"ok":false,"error":{"code":"timeout","message":...}}` (error keys `code` and `message`). Of 12 live terminals tried, 8 answered satisfied and 4 answered `timeout`. | `waitSatisfied` reads `satisfied` from `result` or `result.wait`, and takes exit 1 with code `timeout` as "not satisfied", not a failure. |
|
|
19
|
+
| `worktree current --json` | In a directory Orca manages: exit 0, `ok: true`, `result.worktree`. | Nothing in `terminal-recovery.ts` or the terminal opener runs it. It was observed because #1090 names it. The opener (#1089) uses `worktree list` instead. |
|
|
20
|
+
| `worktree list --json` | exit 0, `ok: true`. `result` holds `worktrees`, `totalCount`, `truncated` and `hostScope`. A row holds `id`, `path`, `isArchived`, `isMainWorktree` and others. | `resolveStartTerminalWorktree` (#1089) matches the one non-archived row whose `path` equals the project root, and refuses on a `truncated` list that lacks it. |
|
|
21
|
+
|
|
22
|
+
## Error codes the code depends on
|
|
23
|
+
|
|
24
|
+
| Code | How it was observed | Expected by the code |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| `terminal_handle_stale` | `terminal show` and `terminal wait` with a made-up handle: exit 1, `ok: false`, `error` keys `code`, `data` and `message`, the code printed on stdout with nothing on stderr. | `run()` turns it into the `terminal-gone` blocker. It reads the code from stdout JSON, or from stderr JSON when stdout has none. |
|
|
27
|
+
| `timeout` | `terminal wait` with a 1 ms timeout on a terminal that was not idle: exit 1, `error` keys `code` and `message`. | `waitSatisfied` treats exit 1 with this code as `false`. Any other failure still throws. |
|
|
28
|
+
| `selector_not_found` | `worktree current` run in a temporary directory Orca does not manage: exit 1, `ok: false`. | Not read by the code. Recorded because it is the answer a start gets when the project is not in Orca, which `resolveStartTerminalWorktree` handles as "no match". |
|
|
29
|
+
|
|
30
|
+
## Observations that are not contract breaks
|
|
31
|
+
|
|
32
|
+
- `terminal list` rows carry `worktreePath` as a plain string. The code reads it with `nestedString(row, ["worktreePath", "projectRoot"])`, which is a list of alternative top-level names, not a path into a nested object. It returns the string, so the root comparison works on 1.4.245. The call reads like a nested lookup; it is not one.
|
|
33
|
+
- `agentIdentity` was a string on rows that had one and `null` on the rest (22 of 39 rows had one, with kinds `claude`, `codex`, `jcode`, `kimi` and `pi`). Rows have no `agent` or `session` field of their own. The code tries several names and takes the first that names a known adapter, so this is covered.
|
|
34
|
+
- `terminal list --json` returned all 39 terminals with `truncated: false`, so the complete-inventory path was the one exercised. What Orca does with more terminals than one page holds was not tried; the code treats `truncated: true` as an unknown inventory and refuses to act on it, and that path is covered by the fixture tests only.
|
|
35
|
+
|
|
36
|
+
## Unverified, with the reason
|
|
37
|
+
|
|
38
|
+
| Command or behaviour | Why it is unverified |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `terminal create --worktree id:<id> --command ... --title ... --json` and the handle in its reply | It creates a live pane in the person's Orca. |
|
|
41
|
+
| `terminal close --terminal <handle> --json` | It closes a live pane. |
|
|
42
|
+
| `terminal switch --terminal <handle>` (named in a recovery next-step message) | It switches the person's active tab. |
|
|
43
|
+
| `terminal send`, `terminal read`, `terminal rename`, `terminal split`, `terminal set-pane-title` | The code does not call them. |
|
|
44
|
+
| The `orphaned: true` answer and a `connected: false` row | Every live row had `orphaned: false`. Forcing one needs a detached pane. |
|
|
45
|
+
| A `truncated: true` terminal or worktree list | The inventories were complete. |
|
|
46
|
+
| Remote servers (`--pairing-code`, `--environment`) | The code does not pass them. |
|
|
47
|
+
| The Linux binary (`orca-ide`) and `orca-dev` | The recheck ran the macOS `orca` only. |
|
|
48
|
+
|
|
49
|
+
## Version drift
|
|
50
|
+
|
|
51
|
+
Orca exposes `--version`, but agent-hub has no check for it, unlike the agent CLIs (`src/adapters/compat.ts`). This recheck is by hand. A later change could record `orca --version` next to a recovery plan and say when it differs from the version in the code comment. That is not done here and is not required by #1090's acceptance criteria.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# 0.29.0 release verification
|
|
2
|
+
|
|
3
|
+
This record covers release preparation and source review. It claims no installation, no running-hub upgrade to 0.29.0 and no live TUI launch.
|
|
4
|
+
|
|
5
|
+
## Candidate
|
|
6
|
+
|
|
7
|
+
Version 0.29.0, prepared from main 5943bc6c (11 commits since v0.28.0, 4 of them `feat`; bump rule: minor). The release commits carry the version, the CHANGELOG section, the bundle and the documentation stamps.
|
|
8
|
+
|
|
9
|
+
## Reviews
|
|
10
|
+
|
|
11
|
+
Pull requests named by the commits since v0.28.0: #1129, #1132, #1133, #1134, #1131, #1128, #1123, #1130, #1115, #1127, #1125, #1124, #1120, #1122.
|
|
12
|
+
|
|
13
|
+
Each merged with `gh pr merge --squash --match-head-commit <head>` after a claude `hub_review` approval, with exact-head CI green on ubuntu and macOS (seeded guards included), no unresolved review thread and no pending change request. Every approval is bound at the merged head (`sdlc.reviewedHead` equals the PR head):
|
|
14
|
+
|
|
15
|
+
- #1122 (task 667, #1120) at 2be1975f; #1124 (668, #1121) at 20544df9; #1125 (669, #1078 findings, docs only) at c45d5999.
|
|
16
|
+
- #1127 (670, #1115) at a274bf04, after a macOS-only failure of a test that asserted a sandboxed `git commit` fails; that failure came from a local signing config, and the assertion moved to #1130.
|
|
17
|
+
- #1130 (672, #1123) at 3885038c; #1128 (671, #1126) at 57820fca, rebased once after #1127 and #1130 with every commit unchanged in range-diff.
|
|
18
|
+
- #1131 (675, agent-mem 0.20.0) at 2a28c2bb; a duplicate handoff of the same pin raise (task 677) was cancelled by the person.
|
|
19
|
+
- #1134 (678) at e7bdab10: a Qwen fixture whose synthetic PIDs could equal the runner's PID (seen once in a dgx02 gate), fixed in the fixture under an explicit test-edit ruling.
|
|
20
|
+
- #1133 (674, #1126 follow-up) at 870ddde7, after a codex-connector thread showed an always-true privacy stub in an extracted fixture (tests.md rule); fixed with the real guards and resolved.
|
|
21
|
+
- #1132 (673, #1129) at 6f7f65f0, after two hosted-CI failures: daemon fixtures that route implement work to Pi or local outside a repository, then two tests run in the agent-hub checkout, where the runner's `includeIf` credentials entry makes the hub refuse a worktree. Both fixed in fixtures only; the second was reproduced in a scratch clone first.
|
|
22
|
+
- No merge was bound to an approval at an earlier head.
|
|
23
|
+
|
|
24
|
+
## Native acceptance receipts
|
|
25
|
+
|
|
26
|
+
Receipts added under `docs/verification/` since v0.28.0: `docs/verification/2026-11-03-control-write-stall-windows.json`, `docs/verification/2026-11-03-control-write-stall-windows.md`, `docs/verification/2026-11-03-live-board-latency.json`, `docs/verification/2026-11-03-live-board-latency.md`.
|
|
27
|
+
|
|
28
|
+
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.29.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.
|
|
29
|
+
|
|
30
|
+
## Document review
|
|
31
|
+
|
|
32
|
+
Stale at preparation: README.md, docs/agent-notes/{README,adapters,benchmarks,budget,bus,daemon,local-worker,tasks,tests}.md, docs/operations.md, docs/quickstart.md and docs/security.md. Each was read against the commits since its stamp (3efa678d for most, b26fcd12 for operations.md, aaccc30b for local-worker.md, 36455498 for tests.md). src/cli/help.ts was not stale: no command or flag changed (the only CLI source change is the `ahub status --full` counter line in src/cli/output.ts).
|
|
33
|
+
|
|
34
|
+
- README.md: Status line (release-prepare) and the report link moved to this file.
|
|
35
|
+
- docs/quickstart.md: v0.29.0 install tag, an "Upgrading to 0.29.0" section (amem upgrade together, the sandbox git refusal and the hub commit, control-write diagnostics), and the agent-mem pin 0.19.0 -> 0.20.0 in two places.
|
|
36
|
+
- docs/operations.md: guide header and protocol-window row (0.26.0 through 0.29.0; window unchanged at 16 through 17). The #1115, #1123, #1126 and #1129 sections were written by their PRs and checked.
|
|
37
|
+
- docs/security.md: a control-write diagnostics bullet (metadata only, unauthenticated frames never inspected, caps, opt-in client timing). The #1115, #1123 and #1129 paragraphs were written by their PRs and checked.
|
|
38
|
+
- docs/agent-notes/local-worker.md: the #1115 line still said a sandboxed command can write `.git/refs/heads/*` and worktree admin files and that deny.ts stays unchanged; corrected for #1123, and the list of what the sandbox cannot write now names refs, packed-refs, HEAD and worktree admin files.
|
|
39
|
+
- docs/agent-notes/tasks.md: a stale-head re-file rule (#1121, #1124).
|
|
40
|
+
- docs/agent-notes/daemon.md: a control-write diagnostics rule (#1126: wrapper name for the native-branch ratchet, no traversal before admission, primitive guards, lazy screens, no timeout or authority on this path).
|
|
41
|
+
- docs/agent-notes/tests.md: a rule that a daemon fixture routing write-class work to Pi or local runs in a `gitProject()` repository, never the agent-hub checkout (#1129).
|
|
42
|
+
- docs/agent-notes/{README,adapters,benchmarks,budget,bus}.md: read against the daemon.ts, deny.ts and tools.ts changes; no statement became wrong (the native-branch ratchet is unchanged because the telemetry wrapper keeps the original `onMessage`).
|
|
43
|
+
|
|
44
|
+
All thirteen were restamped with `--reviewed` at 0d0a362c, the branch commit holding these edits.
|
|
45
|
+
|
|
46
|
+
## Checks
|
|
47
|
+
|
|
48
|
+
- `node scripts/check-docs.mjs --require-fresh` before the merge: 0 stale documents (it refuses only for the missing release merge commit, by design).
|
|
49
|
+
- `node scripts/check-package.mjs`: `package: OK (753 files, @staix/agent-hub@0.29.0)`.
|
|
50
|
+
- `bun scripts/build.mjs --check`: the bundle matches the pinned Bun 1.4.2 build.
|
|
51
|
+
- `bun x tsc --noEmit` and the full suite on ubuntu and macOS with the seeded guards: run by the release PR's exact-head CI (heavy checks run only on CI or dgx02 on this machine).
|
|
52
|
+
|
|
53
|
+
## Known gaps, not blocking
|
|
54
|
+
|
|
55
|
+
- No installation and no running-hub upgrade to 0.29.0 is claimed. The running hub on this machine is a 0.27.0 capture, so the #1126 diagnostics have recorded nothing live yet, and recording consent for this release needs the person-approved temporary copy of `scripts/check-docs.mjs` into that capture (#1120 is fixed by this release, so captures of 0.29.0 and later carry the checker).
|
|
56
|
+
- No live receipt for a Pi or local worker accepting, editing and finishing write-class work through the hub worktree and commit (#1115, #1129), nor for the sandbox refusals with a real Pi turn (#1123); each is covered by real git and real `sandbox-exec` fixture tests only (`sandbox-exec` tests run on macOS only).
|
|
57
|
+
- #1078: the cause of the live write stalls is still unknown; the diagnostics that should name it ship in this release.
|
|
58
|
+
- #676 (TaskWorktrees.create runs about 14 sync git calls, about 210 ms per sandboxed write-class accept) was deferred: making it async would break the synchronous accept gate (#1080). Measurements are in hub memory.
|
|
59
|
+
- amem 0.20.0 activation on installed hooks and CLIs is the person's step and is not part of this release.
|