Repository navigation
A forward that T3 refuses is dropped with a notice instead of retried forever #74
Description
Outcome
When T3 refuses a forwarded comment or body edit (MessageRejectedError), the factory drops that item, tells the issue once, and carries on with the rest. Today it resends the same command id on every pass, holds the gate, and sits in building until the time limit.
Acceptance criteria
- A forwarded comment that T3 refuses is dropped. The factory posts the dropped-comment notice (
droppedComment, the same fixed words and link as the other drop reasons) with a new reason, "T3 refused it". Then it writes thecomment-dropped <id>step. That comment is never sent again, and the notice is posted once, at-least-once like the other drop notices. - A forwarded body edit that T3 refuses is dropped. The factory posts one notice in its own fixed words, quoting nothing from the body: "The factory did not send the edited issue body to the build session, because T3 refused it. Post the change as a new comment and the factory will send it." Then it writes a step that marks that
edited_atas handled, so the same edit is not sent or reported again. A newer edit is still forwarded. - A refusal does not stop the call. The comments and edit after the refused item in the same call are still sent in order.
- A refused item counts as not sent. A call whose every send was refused does not hold the gate. A
forward-waitwritten in that call does not keepadvanceansweringrunning, because no message started a run. - Any other send failure (transport, timeout) behaves as it does today: the call stops and the item is retried on the next pass. A thread that is gone keeps today's handling.
- The ported tests in
apps/server/src/factory/runner/forward.test.tsthat pin retry-on-refusal ("a send T3 refuses fails the call and records nothing for it", and the refusal case of "a failed send stops the call…") are changed to the new rule. Each one says it departs from softfac on purpose. - New unit tests cover: a refused comment (notice and step, never resent), a refused body edit (notice and step, a newer edit still sent), a refusal between two sendable comments, a pass where every send was refused (the gate is not held), and a crash between the notice and its step (posted again, then recorded).
Depends on
Notes
Found in review of PR #73 (finding f1). It was settled there as a faithful port of softfac bf273a1, which has the same bug: the runner's forward treats every send error as transient. A refused command id stays refused, because T3 keeps the refusal under that id (see the comment at the reminder's send in apps/server/src/factory/runner/building.ts), so a resend can never succeed.
The new body-edit step is a departure from softfac's ledger format. Name it after the existing steps (for example body-edit-dropped <edited_at>), and make the ledger reader treat it like body-edit-forwarded for "already handled".
Leave at factory:proposed until the fork's factory watches this repo (same as #22).
Activity
[-]A forward that T3 refuses makes the run stuck instead of retrying forever[/-][+]A forward that T3 refuses is dropped with a notice instead of retried forever[/+]rawphp commentedon Oct 16, 2026
Factory status: pr-open
test(factory): a sent edit keeps the forward-wait its refused comment…