CB-548: harden send ownership and rendezvous routing #23

Merged
ltms merged 2 commits from worker/cb-548-rendezvous-guard-rebased into main 2026-08-13 19:44:02 +02:00
Owner

Rebased replacement for #21 on current main (86cf4c2).

  • Rejects rendezvous double-open instead of replacing a live waiter.
  • Records per-target delegator ownership only for a send that wins admission; BUSY attempts cannot steal routing.
  • Prevents architects from claiming the legacy singleton primary fallback.
  • Opens the waiter before callback/enqueue, closing the fast-reply race and cleaning callback failures.
  • Preserves bridge_ask answer ownership.

Independent review found no blocking defects. Exact rebased head: mvn clean install -> Tests run: 540, Failures: 0, Errors: 0, Skipped: 0; BUILD SUCCESS.

The review's low residual is accepted: ownership records on lock admission before eventual physical injection, so a later queued timeout may leave a transient stale nudge target. This is preferable to waiting for physical delivery because the worker may be busy for the full caller window; the next accepted turn replaces it, and durable replies remain pullable.

Rebased replacement for #21 on current main (`86cf4c2`). - Rejects rendezvous double-open instead of replacing a live waiter. - Records per-target delegator ownership only for a send that wins admission; BUSY attempts cannot steal routing. - Prevents architects from claiming the legacy singleton primary fallback. - Opens the waiter before callback/enqueue, closing the fast-reply race and cleaning callback failures. - Preserves bridge_ask answer ownership. Independent review found no blocking defects. Exact rebased head: `mvn clean install` -> Tests run: 540, Failures: 0, Errors: 0, Skipped: 0; BUILD SUCCESS. The review's low residual is accepted: ownership records on lock admission before eventual physical injection, so a later queued timeout may leave a transient stale nudge target. This is preferable to waiting for physical delivery because the worker may be busy for the full caller window; the next accepted turn replaces it, and durable replies remain pullable.
ltms added 2 commits 2026-08-13 19:43:49 +02:00
Record PrimaryRegistry delegator ownership via a MessageService accepted-delivery
hook (won the session lock + queued delivery), never at bridge_send request time, so
a concurrent sender that times out BUSY cannot steal a live turn's reply routing.
Make Rendezvous.open atomic fail-if-present so a double open trips loudly instead of
replacing the waiter another send is blocked on. Answering a bridge_ask keeps the same
ownership (no rewrite). Adds ownership/rendezvous regression tests.
CB-548: guard primary singleton to PRIMARY callers; open waiter before enqueue
CI / contract (pull_request) Successful in 42s
CI / build (pull_request) Successful in 53s
dd906526c0
Fix two handler-level bugs found in PR #21:
- Only PRIMARY callers may update PrimaryRegistry.record (the legacy singleton 'primary'
  fallback for no-delegation inbox nudges). An architect SEND previously recorded its terminal
  as the fallback; the per-target delegation map does not cure the singleton. New
  BridgeMcp.recordPrimarySingleton uses the resolved role (caller.isPrimary()) — named leads
  (PRIMARY) still record, architects never do.
- MessageService.send now opens the rendezvous waiter BEFORE queueing delivery, fixing both the
  enqueue-before-open fast-reply race (a fast reply no longer orphans into the inbox) and
  callback-failure ordering: a throwing onAccepted (public callback) fails the send cleanly with
  no stale waiter and no queued, orphanable message.

Tests: architect SEND vs lead SEND primary-singleton regression; throwing onAccepted leaves no
stale waiter or queued orphan.
ltms merged commit 91c9f981c5 into main 2026-08-13 19:44:02 +02:00
Sign in to join this conversation.