@@ -152,8 +152,11 @@ Existing wait helpers therefore see `targets=[]` for `#channel` sends and return
152152immediately. For #147 , that must NOT count as committed delivery. Engage
153153provisional -> commit-on-injected only when there is at least one concrete agent
154154target. Empty-target/channel sends keep prior semantics, are logged as residual,
155- and must never be falsely committed. The long-term fix is for the broker send
156- response to include resolved targets.
155+ and must never be falsely committed. Mixed direct-agent plus channel batches use
156+ the same conservative behavior for the whole batch: no injected-delivery claim
157+ is committed, so direct-agent recipients in that mixed batch do not get #147
158+ re-drive protection. The long-term fix is for the broker send response to
159+ include resolved targets.
157160
158161File ownership for implementation:
159162
@@ -226,19 +229,15 @@ same provisional/committed state keyed by `eventDedupeKeyWithFingerprint()`.
226229 - On ` delivery_injected ` : mark that recipient confirmed.
227230 - When all recipients are confirmed: commit the claim and extend ` expiresAt `
228231 to the normal replay TTL.
229- - On failure or timeout: mark failed and release the provisional claim if no
230- recipient confirmed.
232+ - On failure or timeout: mark failed and release the provisional claim.
2312337. If every recipient fails synchronously before send acceptance, release the
232234 claim immediately as today.
233- 8. If some recipients confirm and some fail, commit for confirmed recipients and
234- log/telemetry the partial failure. A later replay should target only missing
235- recipients if recipient-scoped tracking is implemented in the same pass;
236- otherwise release the whole claim to prefer duplicate delivery over message
237- loss.
238-
239- The first implementation should prefer whole-claim release on partial failure.
240- It may duplicate a message for a recipient that already got it, but it avoids the
241- known worse behavior of losing human instructions.
235+ 8. If some recipients confirm and some fail, release the whole shared logical
236+ claim rather than committing on first success. A later replay re-sends to all
237+ recipients, so recipients that already received the steer may see a duplicate.
238+ That is the accepted duplicate-over-drop bias for #147. True per-recipient
239+ claims could avoid the duplicate, but they add complexity and are out of
240+ scope for this pass; the live drop path is single-recipient ( ` slack -comms ` ).
242241
243242## Timeout And Telemetry
244243
@@ -302,6 +301,8 @@ Add broker tests for relay-worker's helper extension:
3023011. Land #145 and restart Pear on it to restore reliable content reads.
3033022. Direct-agent implementation uses ` delivery_injected ` with a 5-second timeout.
304303 Channel/unresolved targets remain residual and never commit on ` targets =[]` .
304+ Mixed direct-agent plus channel batches also keep prior semantics for the
305+ whole batch.
3053063. pear-worker adds the additive BrokerManager helper and bridge state machine;
306307 relay-worker adds helper tests.
3073084. Implement #147 as a follow-up stacked from #145/main using that helper as the
0 commit comments