@staix/agent-hub 0.12.29 → 0.12.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +92 -218
  3. package/docs/agent-notes/README.md +12 -0
  4. package/docs/agent-notes/adapters.md +3 -2
  5. package/docs/agent-notes/budget.md +1 -1
  6. package/docs/agent-notes/bus.md +7 -1
  7. package/docs/agent-notes/daemon.md +14 -1
  8. package/docs/agent-notes/local-worker.md +4 -2
  9. package/docs/agent-notes/tasks.md +14 -0
  10. package/docs/agent-notes/tests.md +6 -3
  11. package/docs/memory.md +70 -152
  12. package/docs/operations.md +317 -25
  13. package/docs/plans/2026-10-16-amem-failure-registry.md +101 -0
  14. package/docs/plans/2026-10-16-amem-p0-baseline.md +110 -0
  15. package/docs/plans/2026-10-16-amem-p2-read-tools.md +28 -0
  16. package/docs/plans/amem-cases.json +482 -0
  17. package/docs/quickstart.md +24 -2
  18. package/docs/security.md +42 -2
  19. package/docs/smoke.md +11 -0
  20. package/docs/specs/2026-09-19-agent-hub-design.md +142 -7
  21. package/docs/specs/2026-09-20-upgrade-recovery-design.md +84 -10
  22. package/docs/verification/2026-10-17-0.12.30.md +70 -0
  23. package/docs/verification/2026-10-17-0.12.31.md +71 -0
  24. package/docs/verification/2026-10-17-418-probes.md +21 -0
  25. package/docs/verified.json +13 -13
  26. package/package.json +5 -2
  27. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  28. package/plugins/agent-hub/server.js +129 -62
  29. package/src/adapters/claude-channel.ts +29 -11
  30. package/src/adapters/local-worker.ts +2 -2
  31. package/src/adapters/pi.ts +5 -0
  32. package/src/cli/attention.ts +5 -1
  33. package/src/cli/console-state.ts +145 -29
  34. package/src/cli/console.ts +40 -10
  35. package/src/cli/help.ts +3 -2
  36. package/src/cli/identity.ts +4 -3
  37. package/src/cli/jcode-mcp.ts +1 -1
  38. package/src/cli/main.js +2 -2
  39. package/src/cli/main.ts +43 -14
  40. package/src/cli/memory.ts +87 -187
  41. package/src/cli/output.ts +19 -2
  42. package/src/cli/recovery-package.ts +59 -10
  43. package/src/cli/upgrade-interactive.ts +2 -1
  44. package/src/cli/upgrade-restore-state.ts +133 -0
  45. package/src/cli/upgrade-runtime.ts +204 -63
  46. package/src/cli/upgrade.ts +57 -24
  47. package/src/hub/board.ts +83 -24
  48. package/src/hub/bus.ts +108 -38
  49. package/src/hub/check-runner.ts +514 -0
  50. package/src/hub/child-process.ts +1 -0
  51. package/src/hub/control-client.ts +5 -1
  52. package/src/hub/daemon.ts +529 -89
  53. package/src/hub/delivery-hints.ts +30 -0
  54. package/src/hub/delivery-journal.ts +185 -12
  55. package/src/hub/delivery-superseded.ts +52 -0
  56. package/src/hub/envelope.ts +31 -1
  57. package/src/hub/git.ts +2 -38
  58. package/src/hub/host-executable.ts +11 -0
  59. package/src/hub/hub-tools.ts +14 -2
  60. package/src/hub/manager.ts +1 -1
  61. package/src/hub/memory-candidates.ts +103 -0
  62. package/src/hub/memory-fail.ts +25 -0
  63. package/src/hub/memory-observations.ts +47 -0
  64. package/src/hub/memory-plan-guard.ts +33 -0
  65. package/src/hub/memory-policy.ts +42 -0
  66. package/src/hub/memory-profile-check.ts +170 -0
  67. package/src/hub/memory-profile.ts +192 -0
  68. package/src/hub/memory-staleness.ts +55 -0
  69. package/src/hub/path-policy.ts +8 -0
  70. package/src/hub/peer-catalog.ts +3 -0
  71. package/src/hub/project.ts +4 -37
  72. package/src/hub/read-tools.ts +127 -0
  73. package/src/hub/routing.ts +35 -16
  74. package/src/hub/settings.ts +2 -1
  75. package/src/hub/spec-read.ts +120 -0
  76. package/src/hub/supervision.ts +21 -6
  77. package/src/hub/task-sweep.ts +7 -6
  78. package/src/hub/tasks.ts +370 -71
  79. package/src/local/deny.ts +4 -17
  80. package/src/memory/brief.ts +8 -5
  81. package/src/memory/capture.ts +3 -1
  82. package/src/memory/recall.ts +50 -110
  83. package/src/pi/process-signature.ts +2 -42
  84. package/src/ui/index.html +12 -9
  85. package/src/ui/needs.ts +7 -5
  86. package/src/ui/office-model.ts +4 -1
  87. package/src/ui/task-board.ts +1 -1
  88. package/src/ui/task-progress.ts +6 -2
  89. package/templates/AGENTS.block.md +1 -1
  90. package/templates/profiles/general.json +1 -1
  91. package/templates/profiles/research.json +1 -1
  92. package/templates/profiles/writing.json +1 -1
  93. package/src/memory/import.ts +0 -90
  94. package/src/memory/store.ts +0 -805
  95. package/src/memory/sync.ts +0 -145
@@ -0,0 +1,482 @@
1
+ [
2
+ {
3
+ "id": "T01",
4
+ "mode": "Truth/lifecycle",
5
+ "symptom": "Readers with different configured TTLs disagree about expiry.",
6
+ "resolution": "Persist deadlines in entries/settle/demote ops, instead of deriving with reader configuration.",
7
+ "status": "regression-covered",
8
+ "source": "PR #352; test/memory-store.test.ts:140"
9
+ },
10
+ {
11
+ "id": "T02",
12
+ "mode": "Truth/lifecycle",
13
+ "symptom": "A late note on an already approved task has no correct lifetime.",
14
+ "resolution": "Settle old approvals and give late short notes their own clock; approved promotable notes can start long.",
15
+ "status": "regression-covered",
16
+ "source": "PR #352; test/memory-native.test.ts:158; test/memory-store.test.ts:320"
17
+ },
18
+ {
19
+ "id": "T03",
20
+ "mode": "Truth/lifecycle",
21
+ "symptom": "An explicit short-horizon note is promoted on approval or loses its own deadline.",
22
+ "resolution": "Keep explicit short intent and deadline through settlement.",
23
+ "status": "regression-covered",
24
+ "source": "PR #352; test/memory-native.test.ts:190; test/memory-store.test.ts:433"
25
+ },
26
+ {
27
+ "id": "T04",
28
+ "mode": "Truth/lifecycle",
29
+ "symptom": "A crash between board approval, settle append and promotion loses settlement effects.",
30
+ "resolution": "Reconcile approvals at startup and finish logged settlement on later reads.",
31
+ "status": "regression-covered",
32
+ "source": "PR #352; test/memory-native.test.ts:169; test/memory-store.test.ts:140"
33
+ },
34
+ {
35
+ "id": "T05",
36
+ "mode": "Truth/lifecycle",
37
+ "symptom": "Demoting a promoted copy exposes a hidden long-lived original; repeated promotion chains drift.",
38
+ "resolution": "Derive the original/copy chain together for demote/forget operations.",
39
+ "status": "regression-covered",
40
+ "source": "PR #352; test/memory-store.test.ts:178; test/memory-store.test.ts:197"
41
+ },
42
+ {
43
+ "id": "T06",
44
+ "mode": "Truth/lifecycle",
45
+ "symptom": "A superseded settled source expires or fails to return/promote when its replacement disappears.",
46
+ "resolution": "Retain promotable source, derive replacement liveness and promote held sources on forget/expiry.",
47
+ "status": "regression-covered",
48
+ "source": "PR #352; test/memory-store.test.ts:360; test/memory-store.test.ts:379; test/memory-store.test.ts:391; CM #186471"
49
+ },
50
+ {
51
+ "id": "T07",
52
+ "mode": "Truth/lifecycle",
53
+ "symptom": "Promotion changes chronology or drops a replacement relation.",
54
+ "resolution": "Promotion keeps source date/provenance and supersession.",
55
+ "status": "regression-covered",
56
+ "source": "PR #352; test/memory-store.test.ts:415; test/memory-store.test.ts:542"
57
+ },
58
+ {
59
+ "id": "T08",
60
+ "mode": "Truth/lifecycle",
61
+ "symptom": "Local or separately written supersessions form a cycle.",
62
+ "resolution": "Refuse local cycle creation; derive a deterministic broken cycle for split writers.",
63
+ "status": "regression-covered",
64
+ "source": "PR #352; test/memory-store.test.ts:458; test/memory-store.test.ts:472; CM #186635"
65
+ },
66
+ {
67
+ "id": "T09",
68
+ "mode": "Truth/lifecycle",
69
+ "symptom": "An older embedded supersedes relation clobbers a later explicit operation.",
70
+ "resolution": "Fold both sources chronologically with deterministic time/id precedence.",
71
+ "status": "regression-covered",
72
+ "source": "PR #352; test/memory-store.test.ts:485; CM #186788"
73
+ },
74
+ {
75
+ "id": "T10",
76
+ "mode": "Truth/lifecycle",
77
+ "symptom": "Notes on tasks never approved remain forever in the active index.",
78
+ "resolution": "Persist fixed 180-day backstop; keep append-only history.",
79
+ "status": "regression-covered",
80
+ "source": "PR #352; test/memory-store.test.ts:584; docs/memory.md:17"
81
+ },
82
+ {
83
+ "id": "T11",
84
+ "mode": "Truth/lifecycle",
85
+ "symptom": "Model-written answers or unconfirmed inferred relations become circular evidence.",
86
+ "resolution": "Exclude ahub ask answers from import/evidence; keep suggestions non-evidence until a person confirms them.",
87
+ "status": "guard/design",
88
+ "source": "PR #356; src/memory/import.ts:68; test/memory-phase3.test.ts:23; test/memory-phase3.test.ts:57"
89
+ },
90
+ {
91
+ "id": "D01",
92
+ "mode": "Duplicate/identity",
93
+ "symptom": "One claude-mem observation hashes differently on different checkouts or deny settings.",
94
+ "resolution": "Text-only import associations stabilize content identity across machines.",
95
+ "status": "fixed-source",
96
+ "source": "issue #380; PR #389; test/memory-sync.test.ts:188; CHANGELOG.md:26"
97
+ },
98
+ {
99
+ "id": "D02",
100
+ "mode": "Duplicate/identity",
101
+ "symptom": "Legacy duplicate import groups survive sync; naive dedupe can overwrite person replacements.",
102
+ "resolution": "Read-only dedupe plan plus explicit append-only apply, preserve existing replacements and group forget.",
103
+ "status": "fixed-source",
104
+ "source": "issue #380; PR #389; test/memory-dedupe.test.ts:33; test/memory-dedupe.test.ts:61; test/memory-sync.test.ts:218"
105
+ },
106
+ {
107
+ "id": "D03",
108
+ "mode": "Duplicate/identity",
109
+ "symptom": "Two machines promoting one demoted entry can create two copies.",
110
+ "resolution": "Deterministic promotion identity independent of promoting process.",
111
+ "status": "regression-covered",
112
+ "source": "PR #352; test/memory-store.test.ts:497"
113
+ },
114
+ {
115
+ "id": "D04",
116
+ "mode": "Duplicate/identity",
117
+ "symptom": "A previously given short-term id no longer resolves after promotion or on a remote with only the synced copy.",
118
+ "resolution": "Resolve original ids through promotedFrom, locally and remotely.",
119
+ "status": "regression-covered",
120
+ "source": "PR #352; test/memory-store.test.ts:445; test/memory-store.test.ts:522"
121
+ },
122
+ {
123
+ "id": "R01",
124
+ "mode": "Retrieval/capture",
125
+ "symptom": "Native own-platform recall repeats context already injected by hooks.",
126
+ "resolution": "Claude/Codex get other-platform blocks; other peers get combined recall.",
127
+ "status": "guard/design",
128
+ "source": "src/memory/recall.ts:15; test/recall.test.ts:11"
129
+ },
130
+ {
131
+ "id": "R02",
132
+ "mode": "Retrieval/capture",
133
+ "symptom": "The first platform consumes a cross-platform recall budget.",
134
+ "resolution": "Split the budget across returned platform blocks and remove repeated legends.",
135
+ "status": "regression-covered",
136
+ "source": "src/memory/recall.ts:78; test/recall.test.ts:70"
137
+ },
138
+ {
139
+ "id": "R03",
140
+ "mode": "Retrieval/capture",
141
+ "symptom": "A stopped/changed/hung worker could block or fail a turn.",
142
+ "resolution": "2-second fail-open client returns undefined and logs the dropped call.",
143
+ "status": "guard/design",
144
+ "source": "src/memory/client.ts:20; test/memory.test.ts:14"
145
+ },
146
+ {
147
+ "id": "R04",
148
+ "mode": "Retrieval/capture",
149
+ "symptom": "Local-worker summarize was skipped as subagent context.",
150
+ "resolution": "Omit agentId on summarize; live 13.25.1 observation recorded.",
151
+ "status": "historical-fixed",
152
+ "source": "src/memory/capture.ts:74; docs/smoke.md:658"
153
+ },
154
+ {
155
+ "id": "R05",
156
+ "mode": "Retrieval/capture",
157
+ "symptom": "Unawaited session-end disappears when the process exits.",
158
+ "resolution": "Await bounded Capture.end at shutdown.",
159
+ "status": "historical-fixed",
160
+ "source": "src/memory/capture.ts:83; docs/smoke.md:658"
161
+ },
162
+ {
163
+ "id": "R06",
164
+ "mode": "Retrieval/capture",
165
+ "symptom": "A new fail note reaches only the next session, after a peer retries the rejected approach.",
166
+ "resolution": "Ride notes on the other peers next delivery, newest ten, without a separate turn.",
167
+ "status": "historical-fixed",
168
+ "source": "CHANGELOG.md:427 (previous repository #68); docs/smoke.md:1092"
169
+ },
170
+ {
171
+ "id": "R07",
172
+ "mode": "Retrieval/capture",
173
+ "symptom": "A failed delivery returns an old preface over a newer preface.",
174
+ "resolution": "Merge/restore the preface without overwriting newer memory.",
175
+ "status": "historical-fixed",
176
+ "source": "CHANGELOG.md:427 (previous repository #68)"
177
+ },
178
+ {
179
+ "id": "R08",
180
+ "mode": "Retrieval/capture",
181
+ "symptom": "Generated guidance treats workflow task/review events as reference-only memory.",
182
+ "resolution": "Distinguish message kinds; only presence recall is reference.",
183
+ "status": "historical-fixed",
184
+ "source": "CHANGELOG.md:526; docs/smoke.md:714 (previous repository #11)"
185
+ },
186
+ {
187
+ "id": "R09",
188
+ "mode": "Retrieval/capture",
189
+ "symptom": "Observer returns prose twice instead of observation XML and drops queued batches.",
190
+ "resolution": "Later observation reports lastSuccess and zero consecutiveFailures; exact dropped data recovery was not established.",
191
+ "status": "historical-partial",
192
+ "source": "CM #119860; CM #120247"
193
+ },
194
+ {
195
+ "id": "R10",
196
+ "mode": "Retrieval/capture",
197
+ "symptom": "Observer allowance/provider failure stops capture.",
198
+ "resolution": "Historical OpenRouter switch restored processing; ongoing cost and maintenance conflict remained.",
199
+ "status": "historical-partial",
200
+ "source": "CM S5886"
201
+ },
202
+ {
203
+ "id": "R11",
204
+ "mode": "Retrieval/capture",
205
+ "symptom": "Plugin registration exists but cache runtime, correct home or recall adapter is absent.",
206
+ "resolution": "Historical cache dependency installation and later dot memory adapter repair; not a current live-readiness claim.",
207
+ "status": "historical-partial",
208
+ "source": "CM S6037; CM #197226; MEMORY.md:177; rollout 01a13bd8, lines 35-37"
209
+ },
210
+ {
211
+ "id": "R12",
212
+ "mode": "Retrieval/capture",
213
+ "symptom": "SessionStart context hooks run before the claude-mem launcher compilation completes.",
214
+ "resolution": "Self-heal completes; identical hook rerun exits zero. Missing-PATH/version-cache hypotheses were disproved.",
215
+ "status": "historical-fixed",
216
+ "source": "CM S11000; CM #191224; CM #191227"
217
+ },
218
+ {
219
+ "id": "R13",
220
+ "mode": "Retrieval/capture",
221
+ "symptom": "Global LIMIT before project filtering starves target imports; repeated runs replay the same window or skip a recreated lower-id source.",
222
+ "resolution": "Project-aware SQL and persisted cursor advance handled rows; restart reconsiders skips; reset compares selected-project candidate ids.",
223
+ "status": "fixed-source",
224
+ "source": "issue #380; PR #389; test/memory-phase3.test.ts:120; test/memory-phase3.test.ts:147; test/memory-phase3.test.ts:171; commit d5738472"
225
+ },
226
+ {
227
+ "id": "X01",
228
+ "mode": "Project isolation",
229
+ "symptom": "Unrelated repositories with the same basename share claude-mem recall/import scope.",
230
+ "resolution": "Native memory origin key fixes its own namespace; claude-mem basename ambiguity remains. Import comment gives no local cure.",
231
+ "status": "open-ceiling",
232
+ "source": "src/memory/import.ts:57; docs/smoke.md:1101; src/memory/recall.ts:98"
233
+ },
234
+ {
235
+ "id": "X02",
236
+ "mode": "Project isolation",
237
+ "symptom": "Importing the whole superproject chain imports another projects notes under this projects policy.",
238
+ "resolution": "Import selects only chain.at(-1), the current source project.",
239
+ "status": "regression-covered",
240
+ "source": "src/memory/import.ts:45; src/memory/import.ts:54; test/memory-phase3.test.ts:23"
241
+ },
242
+ {
243
+ "id": "X03",
244
+ "mode": "Project isolation",
245
+ "symptom": "Native basename/path or unscoped-id lookups collide across projects/machines.",
246
+ "resolution": "Canonical origin key, local path hash fallback, project-scoped id access and native worktree aliases.",
247
+ "status": "regression-covered",
248
+ "source": "test/memory-store.test.ts:140; test/memory-store.test.ts:296; test/recall.test.ts:51"
249
+ },
250
+ {
251
+ "id": "X04",
252
+ "mode": "Project isolation",
253
+ "symptom": "A replacement narrows visibility and suppresses an entry for readers that cannot see the replacement.",
254
+ "resolution": "Reject narrower replacement visibility.",
255
+ "status": "regression-covered",
256
+ "source": "PR #352; test/memory-store.test.ts:284"
257
+ },
258
+ {
259
+ "id": "P01",
260
+ "mode": "Privacy",
261
+ "symptom": "A done/review/unmet/context summary on an ordinary task carries PII to cloud memory.",
262
+ "resolution": "Pattern/screen withheld text remains on board; memory and public peer messages receive no private body.",
263
+ "status": "fixed-source",
264
+ "source": "issue #69; PR #73; issue #185 / PR #192; CHANGELOG.md:363; CHANGELOG.md:232"
265
+ },
266
+ {
267
+ "id": "P02",
268
+ "mode": "Privacy",
269
+ "symptom": "Raw hub tool arguments/results bypass Tasks privacy refusal via local capture.",
270
+ "resolution": "Exclude task/conductor/hub_send capture, keeping ordinary tool capture.",
271
+ "status": "fixed-source",
272
+ "source": "issue #230; PR #237; CHANGELOG.md:188"
273
+ },
274
+ {
275
+ "id": "P03",
276
+ "mode": "Privacy",
277
+ "symptom": "An ordinary local turn reads full PII board rows and then captures/repeats them.",
278
+ "resolution": "Return stubs except during an in-process PII turn; PII turns never capture.",
279
+ "status": "fixed-source",
280
+ "source": "issue #230; PR #237"
281
+ },
282
+ {
283
+ "id": "P04",
284
+ "mode": "Privacy",
285
+ "symptom": "Private path references in text, refs, symbols or Unicode/space paths reach either memory.",
286
+ "resolution": "Check private paths before native/cloud writes and in model-facing records.",
287
+ "status": "regression-covered",
288
+ "source": "test/memory-native.test.ts:204; test/memory-store.test.ts:556; src/hub/tasks.ts:2293"
289
+ },
290
+ {
291
+ "id": "P05",
292
+ "mode": "Privacy",
293
+ "symptom": "A previously accepted/shared/synced note violates the current receiving policy or has sensitive metadata.",
294
+ "resolution": "Rescreen whole records on model-facing reads, including nodes/project/secret patterns.",
295
+ "status": "regression-covered",
296
+ "source": "src/hub/daemon.ts:838; test/memory-store.test.ts:556; src/memory/recall.ts:153"
297
+ },
298
+ {
299
+ "id": "P06",
300
+ "mode": "Privacy",
301
+ "symptom": "Invalid unrelated config field silently empties pii.paths for memory CLI reads.",
302
+ "resolution": "Strict policy load fails closed; malformed present config is distinct from absence.",
303
+ "status": "regression-covered",
304
+ "source": "CM S10834; test/memory-store.test.ts:584; src/cli/memory.ts:32"
305
+ },
306
+ {
307
+ "id": "P07",
308
+ "mode": "Privacy",
309
+ "symptom": "Promotion sends local short notes to synced long-term storage without a current policy verdict.",
310
+ "resolution": "PromotionScreen must promote/keep/skip under source-project policy; rescreen task current paths and hold unknown project.",
311
+ "status": "regression-covered",
312
+ "source": "PR #352; test/memory-store.test.ts:672; test/memory-store.test.ts:691; src/memory/store.ts:327"
313
+ },
314
+ {
315
+ "id": "P08",
316
+ "mode": "Privacy",
317
+ "symptom": "Sync publishes note text to a public remote, or visibility cannot be verified.",
318
+ "resolution": "Known-public refused; unknown visibility only warns (residual policy limit); forget does not purge Git history.",
319
+ "status": "guard/design",
320
+ "source": "PR #354; src/memory/sync.ts:94; test/memory-sync.test.ts:57; docs/memory.md:145"
321
+ },
322
+ {
323
+ "id": "P09",
324
+ "mode": "Privacy",
325
+ "symptom": "Tracked project configuration redirects the cloud memory endpoint to receive task text.",
326
+ "resolution": "Memory endpoint applies only from machine-local untracked configuration, checked by file identity.",
327
+ "status": "fixed-source",
328
+ "source": "issue #17; PR #19; CHANGELOG.md:406"
329
+ },
330
+ {
331
+ "id": "I01",
332
+ "mode": "Index integrity/freshness",
333
+ "symptom": "Malformed, bad-id, non-string or invalid-time synced lines poison derived state.",
334
+ "resolution": "Validate schema/content hash/types/time; skip invalid rows and wait for partial tails.",
335
+ "status": "regression-covered",
336
+ "source": "PR #352; test/memory-store.test.ts:73; test/memory-store.test.ts:178; test/memory-store.test.ts:542; test/memory-sync.test.ts:159"
337
+ },
338
+ {
339
+ "id": "I02",
340
+ "mode": "Index integrity/freshness",
341
+ "symptom": "Truncation or same-size/deep prefix rewrite evades byte-offset indexing.",
342
+ "resolution": "Hash indexed prefixes and rebuild on shrink/change.",
343
+ "status": "regression-covered",
344
+ "source": "PR #352; test/memory-store.test.ts:217; test/memory-store.test.ts:237; test/memory-store.test.ts:255"
345
+ },
346
+ {
347
+ "id": "I03",
348
+ "mode": "Index integrity/freshness",
349
+ "symptom": "A durable log append is reported failed when derived SQLite refresh is busy, encouraging duplicate retries.",
350
+ "resolution": "Return saved id after durable append; mark index stale and log refresh failure.",
351
+ "status": "regression-covered",
352
+ "source": "CM S10834; src/memory/store.ts:223; test/memory-store.test.ts:607"
353
+ },
354
+ {
355
+ "id": "I04",
356
+ "mode": "Index integrity/freshness",
357
+ "symptom": "Catching the failed refresh without retry makes saved notes permanently invisible to this process.",
358
+ "resolution": "Read paths ensure freshness and retry a dirty index.",
359
+ "status": "regression-covered",
360
+ "source": "CM #187423; CM #187425; test/memory-store.test.ts:607"
361
+ },
362
+ {
363
+ "id": "I05",
364
+ "mode": "Index integrity/freshness",
365
+ "symptom": "A long-lived reader misses another processes durable write whose indexing failed.",
366
+ "resolution": "Compare segment shape on reads as well as local stale state.",
367
+ "status": "regression-covered",
368
+ "source": "PR #352; test/memory-store.test.ts:618; src/memory/store.ts:585"
369
+ },
370
+ {
371
+ "id": "I06",
372
+ "mode": "Index integrity/freshness",
373
+ "symptom": "Goal/link/lease and suggestion/verdict reads bypass note freshness recovery.",
374
+ "resolution": "Share ensureFresh across those read families; no new log/index format.",
375
+ "status": "fixed-source",
376
+ "source": "issue #378; PR #379; test/memory-store.test.ts:633; docs/verification/2026-10-14-0.12.24-audit.md:24"
377
+ },
378
+ {
379
+ "id": "I07",
380
+ "mode": "Index integrity/freshness",
381
+ "symptom": "Idle expiry is hidden by view filtering while index rows still differ from rebuild.",
382
+ "resolution": "Prune on read so derived rows and rebuild agree.",
383
+ "status": "regression-covered",
384
+ "source": "PR #352; test/memory-store.test.ts:511"
385
+ },
386
+ {
387
+ "id": "S01",
388
+ "mode": "Sync/concurrency",
389
+ "symptom": "Concurrent first-open or corrupt winning machine.json files yield inconsistent/undefined machine identity.",
390
+ "resolution": "Exclusive creation then common validated reread; malformed id fails store construction.",
391
+ "status": "regression-covered",
392
+ "source": "PR #352; test/memory-store.test.ts:272; test/memory-store.test.ts:360; CM #186471; CM #186474"
393
+ },
394
+ {
395
+ "id": "S02",
396
+ "mode": "Sync/concurrency",
397
+ "symptom": "Killed Git leaves index.lock or interrupted merge, hiding subsequent local entries from sync.",
398
+ "resolution": "Signed machine sync lock serializes Git; clear stale owned Git lock and abort interrupted merge.",
399
+ "status": "regression-covered",
400
+ "source": "PR #354; src/memory/sync.ts:31; test/memory-sync.test.ts:159"
401
+ },
402
+ {
403
+ "id": "S03",
404
+ "mode": "Sync/concurrency",
405
+ "symptom": "Concurrent pushes or absent/unreachable remote make memory transport fail.",
406
+ "resolution": "Own-machine segments, pull/merge, one retry after push race; errors return fail-open result.",
407
+ "status": "guard/design",
408
+ "source": "PR #354; src/memory/sync.ts:61; test/memory-sync.test.ts:33; test/memory-sync.test.ts:57"
409
+ },
410
+ {
411
+ "id": "S04",
412
+ "mode": "Sync/concurrency",
413
+ "symptom": "Two machines claim one goal before synchronization.",
414
+ "resolution": "Advisory earlier-claim winner with conflict displayed; force resolution by person; broker needed for consensus.",
415
+ "status": "open-ceiling",
416
+ "source": "src/memory/store.ts:718; test/memory-sync.test.ts:69"
417
+ },
418
+ {
419
+ "id": "C01",
420
+ "mode": "Scale/cost/measurement",
421
+ "symptom": "Promote check and append race with another processes forget/replacement.",
422
+ "resolution": "Open ceiling: per-machine mutation lock would make check+append atomic.",
423
+ "status": "open-ceiling",
424
+ "source": "src/memory/store.ts:335"
425
+ },
426
+ {
427
+ "id": "C02",
428
+ "mode": "Scale/cost/measurement",
429
+ "symptom": "Every refresh hashes the whole indexed prefix, O(segment bytes).",
430
+ "resolution": "Open ceiling: block hash chain if measured scale warrants it.",
431
+ "status": "open-ceiling",
432
+ "source": "src/memory/store.ts:392"
433
+ },
434
+ {
435
+ "id": "C03",
436
+ "mode": "Scale/cost/measurement",
437
+ "symptom": "Repeated concurrent writers exceed bounded refresh retries.",
438
+ "resolution": "Open ceiling: five retry levels then deferred work; shared read lock is proposed upgrade.",
439
+ "status": "open-ceiling",
440
+ "source": "src/memory/store.ts:430"
441
+ },
442
+ {
443
+ "id": "C04",
444
+ "mode": "Scale/cost/measurement",
445
+ "symptom": "Views materialize/filter all rows in process memory.",
446
+ "resolution": "Open ceiling: SQL filtering when store size warrants it.",
447
+ "status": "open-ceiling",
448
+ "source": "src/memory/store.ts:490"
449
+ },
450
+ {
451
+ "id": "C05",
452
+ "mode": "Scale/cost/measurement",
453
+ "symptom": "Clock rollback resurrects an expired row after rebuild.",
454
+ "resolution": "Open ceiling: durable prune entry, instead of wall-clock-only expiry.",
455
+ "status": "open-ceiling",
456
+ "source": "src/memory/store.ts:569"
457
+ },
458
+ {
459
+ "id": "C06",
460
+ "mode": "Scale/cost/measurement",
461
+ "symptom": "Three-characters-per-token approximation is not an exact token ceiling.",
462
+ "resolution": "Open ceiling: tokenizer if exact bounds are required.",
463
+ "status": "open-ceiling",
464
+ "source": "src/memory/recall.ts:54"
465
+ },
466
+ {
467
+ "id": "C07",
468
+ "mode": "Scale/cost/measurement",
469
+ "symptom": "Dashboard Memory recomputes the whole index per poll.",
470
+ "resolution": "Open ceiling: cache by index revision when measured poll cost warrants it.",
471
+ "status": "open-ceiling",
472
+ "source": "src/hub/daemon.ts:3197"
473
+ },
474
+ {
475
+ "id": "C08",
476
+ "mode": "Scale/cost/measurement",
477
+ "symptom": "Adoption decisions lack causal effectiveness/cost measurements; brief counts cannot prove a failed approach was retried.",
478
+ "resolution": "#247/#248/#258 ship counts/arms/report plumbing; controlled arms, field window and manual retry labels remain owed.",
479
+ "status": "open-measurement",
480
+ "source": "issue #248 AC2-4; issue #258 AC11; PR #351; PR #356; docs/smoke.md:68; docs/research.md:88"
481
+ }
482
+ ]
@@ -4,7 +4,7 @@ agent-hub lets the coding agents on one machine work as peers in one project dir
4
4
 
5
5
  ## Install
6
6
 
7
- Needs [Bun](https://bun.sh) 1.3 or newer and macOS (Linux works without the `local` worker's `bash` and `git` tools, which need the macOS sandbox).
7
+ Needs [Bun](https://bun.sh) 1.4.2 or newer and macOS (Linux works without the `local` worker's `bash` and `git` tools, which need the macOS sandbox).
8
8
 
9
9
  Node alone is not supported. Keep `bun` on PATH even if you install with npm.
10
10
  The registry package uses the `staix` organization scope. Install from npm:
@@ -17,7 +17,7 @@ ahub setup # installs the Claude Code channel plu
17
17
  Or use the matching GitHub release:
18
18
 
19
19
  ```bash
20
- bun add -g github:STAIxBWLB/agent-hub#v0.12.29
20
+ bun add -g github:STAIxBWLB/agent-hub#v0.12.31
21
21
  ahub setup
22
22
  ```
23
23
 
@@ -30,6 +30,19 @@ and upgrade or crash recovery, see the [operations guide](operations.md). To
30
30
  move running projects to a newer release later, run `ahub upgrade` in a
31
31
  terminal: it reviews the plan with you, applies it and follows it.
32
32
 
33
+ ## Upgrading to 0.12.31
34
+
35
+ Existing Jcode project MCP entries need one refresh before conductor or dashboard starts. Once per project, the person runs:
36
+
37
+ ```bash
38
+ ahub jcode --mode headless
39
+ ahub init
40
+ ```
41
+
42
+ The first command starts Jcode and rewrites only the hub-owned `agent-hub-jcode` entry in `.jcode/mcp.json`, adding its delivery-only marker. Foreign or overriding entries refuse instead of being overwritten. `ahub init` keeps an untracked machine-path file out of git; review a tracked file deliberately. Daemon readiness checks never rewrite this entry. See [Jcode operations](operations.md#optional-jcode-peer).
43
+
44
+ Task owners running as Pi or `local` need the isolated test capability for non-PII `implement`, `test` and `bulk_edit` work. A person sets `checks.runner` to `"container"` in untracked `.agenthub/config.local.json`; the Apple container service and pinned image must also be available. Issue-backed owners additionally need spec access. Manual messages remain available, and PII work retains its local-only routing. See [bounded check requirements](security.md#bounded-task-specs-and-isolated-checks-418) before enabling the runner.
45
+
33
46
  ## First session
34
47
 
35
48
  In your project directory, one terminal each:
@@ -68,13 +81,22 @@ or set `OMNIROUTE_API_KEY`. Name the model in `.agenthub/routing.toml` (`[local]
68
81
  | `ahub say [@peer] <text>` | talk; start with `[STATUS]` to let it batch, `[FYI]` for the record only |
69
82
  | `ahub task propose [--class <c>] <title>` | put work on the board; the hub picks an owner and a reviewer, and the class if you name none |
70
83
  | `ahub board` | who has what; `ahub task show <id>` for one task |
84
+ | `ahub task cancel <id> --reason <text>` | close obsolete work without approving it or stopping a native turn |
85
+ | `ahub settings set planner <peer>` | pin the planner; status reports whether it came from settings, roles or the automatic choice |
71
86
  | `ahub status` | peers, queues, pauses; `ahub budget` for quota windows |
87
+ | `ahub memory profile-check` | a person's read-only check of running memory bindings in the current registry |
72
88
  | `ahub ask <question>` | what the board, shared memory and the log say, with the ids the answer rests on |
73
89
  | `ahub stop <peer>` | stop one headless peer (Kimi, headless Pi, `local`); the hub and the other peers keep running |
74
90
  | `ahub kill` | stop the daemon and everything it started |
75
91
 
76
92
  More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-design.md`](specs/2026-09-19-agent-hub-design.md). What it protects and what it does not: [`docs/security.md`](security.md).
77
93
 
94
+ ## Shared memory
95
+
96
+ The hub exact-pins the first-party `@staix/agent-mem` 0.3.0 core. Existing shared-v1 memory remains the default; upgrading does not migrate it. Managed agents use screened `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools, or propose a correction with `hub_memory_correct`; only a person accepts candidates through the supported `amem review` path. Generation candidate acceptance is still refused.
97
+
98
+ Before any real generation migration, upgrade every hub sharing that memory home to 0.12.30 or later and check its authenticated binding with `ahub memory profile-check` in each custom registry. Ready bindings prove compatibility, not an atomic live cutover: quiesce consumers and close their handles before migrating, then reopen through the supported session-preserving lifecycle. Invalid or changed profiles disable native memory without falling back to legacy writes; the bus and board continue. See [memory operations](operations.md#hub-memory) for the remaining rollout gates.
99
+
78
100
  ## Browser dashboard
79
101
 
80
102
  After `ahub up`, run `ahub ui` to open the local dashboard. It refreshes the