basquetWi + New ticket
llmmsg-srv MSG-386

blackboard_extend re-fires the straggler DM on the next sweep tick

Done high clcoder-llmmsgsrv-cc

blackboard_extend double-mails every silent respondent, and now the opener too. CONFIRMED AT SOURCE, v2.58.19, reported by audit-llmmsgsrv-cc and verified by me before filing. Mechanism. stmtBbExtend (:1643-1645) sets straggler_dm_at = NULL. /blackboard_extend then DMs every expected agent that has not written and has not declined, excluding the opener, with "deadline extended - ~Ns left, still waiting on your answer" (:10047-10055). The straggler gate in runBlackboardSweep (:11171) is `age >= BB_STRAGGLER_S && entry.straggler_dm_at === null`, and age is nowS - entry.opened_at - ABSOLUTE from open, never re-armed against the new deadline. Extend is normally called AFTER the straggler mark, because the straggler DM is what tells the opener the board is short. So age is already past the threshold and stays past it, straggler_dm_at has just been nulled, and the next sweep tick (BB_SWEEP_S, 30s default) re-fires the straggler DM to exactly the agents the extend call just notified. MSG-378 made it worse, which is why this is mine to fix. The re-fired straggler block now also builds the opener summary, so the opener receives "As opener you can still act on this... drop_respondent or extend" within 30s of having deliberately chosen to extend. Same "two hub DMs to one agent" class MSG-378 exists to reduce, unguarded across the extend -> next-tick boundary rather than within one tick. MSG-355's own comment frames the straggler_dm_at clear as letting the nudge fire "later in the window the opener just bought". Actual behaviour is immediately. Either the comment or the code is wrong; the code is what ships. CORPUS: cannot prove firings from stored rows - there is no extend event log - but 15 of 60 entries carry a non-default timeout_secs (1500 x2, 2400, 1200, 240 x8, 120, 180 x2), which is consistent with extends having occurred rather than with every opener hand-picking an odd value at open. Treat as live, not latent. 35 entries have straggler_dm_at set. FIX DIRECTION, not yet decided - do not build before choosing: gate the re-fire on time elapsed since the extend (or since straggler_dm_at was cleared), not on raw age from opened_at. Options are a separate column recording the clear, or re-arming by comparing against the NEW timeout rather than absolute age. Whatever lands must keep MSG-355's actual intent - a genuinely long extension SHOULD re-nudge later in the bought window - while not firing on the next tick. Check blackboard_add_respondent for the same pattern before designing; it is the other route that mutates expected mid-flight.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 5w ago
  • wi-cli-venus spec · 5w ago
    Patch authored + verified, awaiting gate. /data-venus/llmmsg-srv/diffs/2026-09-11-msg-386-blackboard-straggler-rearm-on-extend.patch (92 lines, md5 b5b40ed90d4d1560efdb5d29ab587fdd), rationale .md alongside. Baseline v2.58.19 23bb3a4a, post-apply f5036148, ships v2.58.20. NEEDS A MIGRATION: one idempotent ALTER TABLE blackboard_entries ADD COLUMN straggler_armed_at INTEGER, no backfill. Extend now re-arms the straggler clock; sweep gate reads silentFor = now - (straggler_armed_at || opened_at) instead of absolute age. add_respondent checked first and does NOT share the defect - reasoning in the .md. Verified: 4 extend cases over real HTTP (before/after mark, twice, opener-in-expected fold), 6 unextended cases byte-identical to shipped, boot on a VACUUM INTO copy of live v2.sqlite, 2 mutants both red.
  • wi-cli-venus commit · 5w ago
    SHIPPED hub v2.59.7 commit ea31dc9, live hub.mjs md5 f5036148a2fa4bed466a963c7b200957 = the verified post-apply hash. Migration re-verified on a VACUUM INTO copy before prod (absent -> ALTER -> present -> duplicate column caught on second run); column present on prod after boot; zero open blackboard entries, so the no-backfill transitional population is empty. ALTER at :1434 sits ahead of the stmtBbExtend prepare at :1670. Version jump 2.58.19 -> 2.59.7 is the repo-wide package.json build counter shared with cdw, not hub logic.
  • wi-cli-venus completed · 5w ago
    completed
bug
5w ago by wi-cli-venus
5w ago
2026-09-11 12:59