fleetd #551: record the delivery attempt before the irreversible send #569

Merged
ltms merged 3 commits from worker/551-record-before-send-7cbf56-1 into main 2026-09-12 13:19:20 +02:00
Member

Fixes #551.

The Injector wrote the delivery outcome AFTER calling AgentControl.send(), so a HerdrException thrown from the response half of that call (herdr already replied, or may have) was recorded as a confident NOT_DELIVERED for text that may already be sitting in the worker's pane.

The entry is now polled off the queue and marked Pending.State.ATTEMPTED (new third state) BEFORE send() is called, not after. On success it is upgraded to DELIVERED; on an ordinary failure it stays ATTEMPTED (honest uncertainty); a herdr *_not_found error still writes NOT_DELIVERED, consistent with how the rest of the codebase already treats that error family as a confirmed absence.

cancellationOf gets a matching third answer (Cancellation.ATTEMPTED) instead of folding the new state into NOT_DELIVERED.

Out of scope, noticed while implementing: MessageService.send's timeout path (line ~973) checks injector.cancel(delivery) == Injector.Cancellation.DELIVERED only, collapsing the new ATTEMPTED (and CANCELLED/NOT_DELIVERED) into Outcome.TIMED_OUT_QUEUED, whose javadoc promises 'on every route it will not arrive later' -- which is no longer true for ATTEMPTED. Not fixed here; flagging for a follow-up ticket.

Build: mvn -o clean install, exit 0, Tests run: 1754, Failures: 0, Errors: 0 (baseline 1750 + 4 new tests), independent surefire sum agrees (1754), 130 report files (unchanged from baseline).

Fixes #551. The Injector wrote the delivery outcome AFTER calling AgentControl.send(), so a HerdrException thrown from the response half of that call (herdr already replied, or may have) was recorded as a confident NOT_DELIVERED for text that may already be sitting in the worker's pane. The entry is now polled off the queue and marked Pending.State.ATTEMPTED (new third state) BEFORE send() is called, not after. On success it is upgraded to DELIVERED; on an ordinary failure it stays ATTEMPTED (honest uncertainty); a herdr *_not_found error still writes NOT_DELIVERED, consistent with how the rest of the codebase already treats that error family as a confirmed absence. cancellationOf gets a matching third answer (Cancellation.ATTEMPTED) instead of folding the new state into NOT_DELIVERED. Out of scope, noticed while implementing: MessageService.send's timeout path (line ~973) checks injector.cancel(delivery) == Injector.Cancellation.DELIVERED only, collapsing the new ATTEMPTED (and CANCELLED/NOT_DELIVERED) into Outcome.TIMED_OUT_QUEUED, whose javadoc promises 'on every route it will not arrive later' -- which is no longer true for ATTEMPTED. Not fixed here; flagging for a follow-up ticket. Build: mvn -o clean install, exit 0, Tests run: 1754, Failures: 0, Errors: 0 (baseline 1750 + 4 new tests), independent surefire sum agrees (1754), 130 report files (unchanged from baseline).
agent added 1 commit 2026-09-12 12:43:55 +02:00
fleetd #551: record the delivery attempt before the irreversible send
CI / shell-tests (pull_request) Successful in 5s
CI / contract (pull_request) Successful in 57s
CI / build (pull_request) Successful in 2m23s
d83821bbce
The Injector wrote the delivery outcome AFTER calling AgentControl.send(),
so a HerdrException thrown from the response half of that call (herdr
already replied, or may have) was recorded as a confident NOT_DELIVERED
for text that may already be sitting in the worker's pane.

Poll the queue entry and mark it Pending.State.ATTEMPTED before send() is
called, not after. On success it is upgraded to DELIVERED; on an ordinary
failure it stays ATTEMPTED (honest uncertainty), except a herdr
*_not_found error, which the rest of this codebase already treats as a
confirmed absence and which now still writes NOT_DELIVERED.

cancellationOf gets a matching third answer (Cancellation.ATTEMPTED)
instead of folding the new state into NOT_DELIVERED, so a caller that
cancels an already-attempted delivery is told the truth too.
agent added 1 commit 2026-09-12 12:51:35 +02:00
fleetd #551 rework (comment 17058): fix TIMED_OUT_QUEUED javadoc for ATTEMPTED
CI / shell-tests (pull_request) Successful in 13s
CI / contract (pull_request) Successful in 1m16s
CI / build (pull_request) Successful in 2m21s
68b428c484
Javadoc-only change. #551 added Injector.Cancellation.ATTEMPTED, which
MessageService.send's timeout path folds into Outcome.TIMED_OUT_QUEUED
alongside CANCELLED and NOT_DELIVERED (the collapse itself is unchanged
behaviour and is being tracked as a separate follow-up ticket).

TIMED_OUT_QUEUED's javadoc — landed by #513 to state the routes that
reach it — named only two routes and said "on every route it will not
arrive later", with a "may already hold a partial paste" caveat. Both
claims are now stale: ATTEMPTED is a third route, and because
agent.prompt pastes AND submits in one call, that route may mean the
target holds a complete, already-submitted turn and is working on it
right now.

Names all three routes, says which one is uncertain, and drops the
now-false blanket claim. No behaviour change.
agent added 1 commit 2026-09-12 13:13:13 +02:00
fleetd #551 shape sweep: fix stale ATTEMPTED-route javadoc/comments in MessageService
CI / shell-tests (pull_request) Successful in 6s
CI / contract (pull_request) Successful in 50s
CI / build (pull_request) Successful in 2m26s
f40c19ecf0
hasQueuedDelivery's javadoc, the queuedDeliveries field javadoc, and a code
comment in send()'s timeout path all still made two claims that ATTEMPTED
(fleetd #551) falsifies: a blanket "the message will not arrive later" across
every route, and "the terminal may already hold a partial paste" — but
agent.prompt pastes AND submits in one call, so the target may hold a
complete, already-submitted turn. Each now names the three Injector.Cancellation
routes (CANCELLED, NOT_DELIVERED, ATTEMPTED) and says plainly that only the
first two establish the message will not arrive later.

Comment/javadoc only. No behaviour change: Injector.java is untouched
(sha256 0c689b6cf36275c0da45497a74b2bd4f5a3d80c4dbda77d46670c66004e53b69) and
no test was added. mvn -o clean install: BUILD SUCCESS, Tests run: 1754,
Failures: 0, Errors: 0 (unchanged from before this commit).
ltms merged commit 384867dfa3 into main 2026-09-12 13:19:20 +02:00
Sign in to join this conversation.