Commit 730e58a
fix(agent,cli,scripts): OT-RFC-38 LU-6 — address Codex PR #610 R1
Five correctness bugs raised on PR #610 by Codex round 1, all addressed.
1. memory.ts /catchup fallback now decides per-CG. Previously the
`totalInserted === 0` gate aggregated across every requested CG,
so a multi-CG catchup where one CG got triples from standard sync
would silently skip LU-6 host-catchup for the others. Restructured
to iterate CGs serially, fan out to peers in parallel within each
CG, and decide host-catchup per CG. The new response shape exposes
per-CG breakdown via `perContextGraph` + `hostCatchup.triggeredFor
ContextGraphIds`, with a backward-compatible flat `results` array
aggregated per peer.
2. memory.ts /catchup `totalInsertedTriples` now includes the
host-catchup applied count. Previously a successful LU-6 recovery
looked like a no-op at the top level (the field only counted
standard sync inserts). Added a separate `standardInsertedTriples`
field for callers that want the pre-fallback figure.
3. host-mode-store.ts seqno recovery from the log tail on cold load.
The log is the source of truth (`appendFile` is durable before
`persistMeta` runs); a crash in between would let the next append
reuse a seqno that was already written, which breaks host-catchup
paging (uses strict-greater-than seqno). `loadMeta()` now scans
the log tail on first access per CG and takes `max(meta.seqno,
lastLogSeqno)`. Reconciled value is persisted so subsequent cold
loads skip the scan. New unit test simulates the stale-meta crash
and verifies the next append picks the right seqno.
4. dkg-agent.ts reconcileSharedMemoryGossipSubscription — clear
`swmHostModeSubscribed` when topic-wide `unsubscribe()` wipes the
host listener. `GossipSubManager.unsubscribe(topic)` removes ALL
handlers on the topic, not just the member-mode one; on member
authorisation revocation that would drop the LU-6 host listener
too, and `reconcileSwmHostModeSubscription()` would early-return
on the still-set `swmHostModeSubscribed` flag — stranding hosting
until restart. Clear the flag before the host-mode reconciler
runs so it re-wires.
5. dkg-agent.ts enableSwmHostModeFor now probes
`isContextGraphRegisteredOnChain` + `markRegistered` on both
first-subscribe and idempotent re-entry. The explicit /host-mode/
subscribe path is the Phase A surface that designates hosting
from a topic id alone (no CG metadata required); without this
probe the store would stay on the 6h/1MiB pre-registration limits
forever, pruning ciphertext from registered CGs much earlier than
intended. Extracted the probe-and-mark step as
`maybeMarkRegisteredForHostMode()` and reused it from both call
sites.
Test harness hardening
- `wait_for_peer_link` helper polls `/api/connections` until a target
peer shows up, with a 90s budget. Use it before SCENARIO C and D
sender-key sends to avoid pre-existing `send timeout: backoff
aborted by overall deadline (20000ms)` flakes after curator restart.
- The flake was not LU-6-related (it pre-dates this PR); the probe
just makes the suite reliable without changing the protocol-level
timeout.
Validation
- All 4 late-joiner devnet scenarios PASS on a fresh
`./scripts/devnet.sh start 6` run. SCENARIO D output now shows
`totalInsertedTriples: 1` (was `0` before R1), `standardInserted
Triples: 0`, `hostCatchup.triggeredForContextGraphIds: ["<CG_D>"]`,
`perContextGraph: [{...perPeer:[...]}]` — all the new visibility
surfaces working.
- `packages/agent/test/swm/host-mode-store.test.ts` — 9 tests pass
(8 original + the new seqno-recovery regression).
- `packages/publisher` test suite — 965 passed / 1 skipped.
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent efb1e1a commit 730e58a
5 files changed
Lines changed: 322 additions & 82 deletions
File tree
- packages
- agent
- src
- swm
- test/swm
- cli/src/daemon/routes
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8389 | 8389 | | |
8390 | 8390 | | |
8391 | 8391 | | |
| 8392 | + | |
| 8393 | + | |
| 8394 | + | |
| 8395 | + | |
| 8396 | + | |
| 8397 | + | |
| 8398 | + | |
| 8399 | + | |
| 8400 | + | |
| 8401 | + | |
| 8402 | + | |
| 8403 | + | |
| 8404 | + | |
| 8405 | + | |
| 8406 | + | |
8392 | 8407 | | |
8393 | 8408 | | |
| 8409 | + | |
8394 | 8410 | | |
8395 | 8411 | | |
8396 | 8412 | | |
| |||
8503 | 8519 | | |
8504 | 8520 | | |
8505 | 8521 | | |
8506 | | - | |
8507 | | - | |
8508 | | - | |
8509 | | - | |
8510 | | - | |
8511 | | - | |
8512 | | - | |
8513 | | - | |
| 8522 | + | |
8514 | 8523 | | |
8515 | 8524 | | |
8516 | 8525 | | |
| |||
8900 | 8909 | | |
8901 | 8910 | | |
8902 | 8911 | | |
| 8912 | + | |
| 8913 | + | |
| 8914 | + | |
| 8915 | + | |
| 8916 | + | |
| 8917 | + | |
8903 | 8918 | | |
8904 | 8919 | | |
8905 | 8920 | | |
| |||
8914 | 8929 | | |
8915 | 8930 | | |
8916 | 8931 | | |
| 8932 | + | |
| 8933 | + | |
| 8934 | + | |
| 8935 | + | |
| 8936 | + | |
| 8937 | + | |
| 8938 | + | |
| 8939 | + | |
8917 | 8940 | | |
8918 | 8941 | | |
8919 | 8942 | | |
8920 | 8943 | | |
8921 | 8944 | | |
8922 | 8945 | | |
8923 | 8946 | | |
| 8947 | + | |
| 8948 | + | |
| 8949 | + | |
| 8950 | + | |
| 8951 | + | |
| 8952 | + | |
| 8953 | + | |
| 8954 | + | |
| 8955 | + | |
| 8956 | + | |
| 8957 | + | |
| 8958 | + | |
| 8959 | + | |
| 8960 | + | |
| 8961 | + | |
8924 | 8962 | | |
8925 | 8963 | | |
8926 | 8964 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
352 | 352 | | |
353 | 353 | | |
354 | 354 | | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
355 | 369 | | |
356 | 370 | | |
357 | 371 | | |
358 | 372 | | |
359 | 373 | | |
| 374 | + | |
360 | 375 | | |
361 | 376 | | |
362 | | - | |
363 | | - | |
364 | | - | |
| 377 | + | |
365 | 378 | | |
366 | | - | |
367 | | - | |
368 | | - | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
369 | 422 | | |
| 423 | + | |
370 | 424 | | |
371 | 425 | | |
372 | 426 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
128 | 162 | | |
129 | 163 | | |
130 | 164 | | |
| |||
0 commit comments