Summary
When the bridge worker's _process_job raises an unhandled exception (subprocess crash, timeout, workspace error), the failure is recorded in SQLite and emitted as a HUD event — but no external signal reaches the PR author or tracking issue. The PR sits indefinitely waiting for a fix that will never arrive, with no visible indication that the autonomous attempt failed.
This is the bridge-worker analog of the CI-side "silent failure-reason loss" fixed by #155, but in the persistent-process path that handles agent:fix events via the webhook→worker pipeline.
Context
bridge/worker.py process_one_job() catches exceptions in two paths: WorkerShutdown (intentional) and generic Exception (crash).
- On generic failure:
db.mark_failed(conn, job.id, traceback) + hud.emit("bridge.job.failed", ...) — both internal-only.
- The tracking issue (created/updated in step 5 of
_process_job) remains open with its last-known content. No comment indicates the attempt failed.
- The PR receives no label change, no comment, no re-request — from the author's perspective, nothing happened.
- The only existing outward signal is
agent-loop-exceeded (iteration cap), which fires in a completely different code path and only on cap exhaustion, not crashes.
Problem
A developer relying on the agent:fix label expects either (a) their PR threads get resolved, or (b) they learn the attempt failed so they can fix it manually. Today, path (b) is invisible unless they check the HUD or bridge logs — artifacts most users never see.
Proposal
Add a failure notification step in the except Exception handler of process_one_job():
- If a
tracking_issue_number was recorded on the job (step 5 succeeded), post a comment:
⚠️ Bridge worker failed to complete this job.
**Error:** <one-line summary, not the full traceback>
**Delivery:** <delivery_id>
The autonomous fix attempt did not produce commits. Manual intervention is needed, or re-trigger by adding the `agent:fix` label again.
- Add the
agent:blocked label to the tracking issue (consistent with CI failure behavior).
- If no tracking issue exists yet (failure in steps 1–4), post a brief comment on the PR itself via the REST API, so the author at minimum sees that the bridge attempted and failed.
The failure comment must:
- Never include the full traceback (may contain tokens/paths).
- Use the already-minted token (which may have expired — guard with try/except and log if notification itself fails).
- Be idempotent: if the job is retried and fails again, don't stack duplicate comments (use a marker string or check for existing failure comments).
Non-goals
- Automatic retry of failed jobs (separate concern; today they stay
failed permanently).
- Surfacing the full traceback externally (security risk).
- Changing the HUD event schema (HUD remains the detailed internal log).
Acceptance criteria
Affected files
bridge/worker.py — process_one_job() exception handler
bridge/github.py — may need a comment_on_pr() helper (or reuse comment_on_issue with PR number)
Relates to
Summary
When the bridge worker's
_process_jobraises an unhandled exception (subprocess crash, timeout, workspace error), the failure is recorded in SQLite and emitted as a HUD event — but no external signal reaches the PR author or tracking issue. The PR sits indefinitely waiting for a fix that will never arrive, with no visible indication that the autonomous attempt failed.This is the bridge-worker analog of the CI-side "silent failure-reason loss" fixed by #155, but in the persistent-process path that handles
agent:fixevents via the webhook→worker pipeline.Context
bridge/worker.pyprocess_one_job()catches exceptions in two paths:WorkerShutdown(intentional) and genericException(crash).db.mark_failed(conn, job.id, traceback)+hud.emit("bridge.job.failed", ...)— both internal-only._process_job) remains open with its last-known content. No comment indicates the attempt failed.agent-loop-exceeded(iteration cap), which fires in a completely different code path and only on cap exhaustion, not crashes.Problem
A developer relying on the
agent:fixlabel expects either (a) their PR threads get resolved, or (b) they learn the attempt failed so they can fix it manually. Today, path (b) is invisible unless they check the HUD or bridge logs — artifacts most users never see.Proposal
Add a failure notification step in the
except Exceptionhandler ofprocess_one_job():tracking_issue_numberwas recorded on the job (step 5 succeeded), post a comment:agent:blockedlabel to the tracking issue (consistent with CI failure behavior).The failure comment must:
Non-goals
failedpermanently).Acceptance criteria
agent:blockedlabel.bridge.job.failedHUD event anddb.mark_failedbehavior are unchanged.Affected files
bridge/worker.py—process_one_job()exception handlerbridge/github.py— may need acomment_on_pr()helper (or reusecomment_on_issuewith PR number)Relates to
decision.blockedevent; this work makes it externally visible, complementing the internal persistence proposed there.