Skip to content

[BUG] Reconcile sweep can never flag a died sidekick: the un-routed check short-circuits the liveness check #995

Description

@TaekeK

What's wrong? (one or two sentences)

The hourly reconcile sweep's died-sidekick detector (💀, added in #963) is unreachable for the issues it was written for. An earlier "no state:* label" branch in dor_reconcile.sh continues past it, and every issue in the build/feedback phase has no state:* label by design — so a dead build is reported as "the agent likely never ran" instead of "its sidekick died, re-dispatch it".

Steps to reproduce

  1. Take an issue through the DoR build side until it is at functional acceptance (build-done, board Status Awaiting functional acceptance).
  2. Comment feedback on it. dor_feedback_flow.sh:32 sets board Status → Building.
  3. Kill the adjustment mid-flight (or let the host reclaim the sidekick, as happened twice on [Feature] Collapse managed resources under business roles in the matrix #370).
  4. Wait for the hourly sweep at :17.

Real occurrence: #370 / PR #933, runs 31016109943 (5 Aug, feedback (sk3) failed 15:02:30Z) and 31076341084 (6 Aug, feedback (sk3) failed 08:41:28Z).

✅ What did you expect to happen?

The sweep flags it with the 💀 rule at dor_reconcile.sh:170-175:

💀 #370 says Building but no DoR workflow run is alive for it (Nm since its last update) — its sidekick almost certainly died mid-flight. It will not move on its own; re-dispatch it.

…and adds it to stalled, which drives the direct comment on the issue at :215.

❌ What actually happened?

The sweep saw Status: Building and still emitted the un-routed message. From the DoR pipeline health issue #886, sweep of 2026-08-06 09:09 UTC:

🕳️ #370 is on the board (Status: Building) with no state:* label after 1151h — the agent likely never ran.

Nothing was flagged as dead, no comment landed on #370, and no sidekick was re-dispatched. The work sat dead for ~18 hours (5 Aug 15:02 → 6 Aug 09:27) across roughly 18 sweeps, until @WimvandenHeijkant noticed by hand and re-posted both rounds of requestor feedback himself.

Root cause

.github/scripts/dor_reconcile.sh:143-150:

if [ -z "$state_label" ]; then
  age_h=$(( (now - created_epoch) / 3600 ))
  if [ "$age_h" -ge "$UNROUTED_HOURS" ]; then
    add_ex "🕳️ #${num} ... with no \`state:*\` label after ${age_h}h — the agent likely never ran."
  fi
  continue        # <-- skips the rest of the loop body
fi

That continue skips everything below it, including the "Building") liveness case at :170 and the zombie-sidekick check at :183.

An issue on the build side has no state:* label by design — the build phase is tracked with build-done / ready-to-build, and dor_build_flow.sh removes state:awaiting-approval when the build starts. #370's labels are enhancement, build-done, sk:sk3. So the whole build/feedback population takes the un-routed branch, which is precisely the population the 💀 rule exists for.

Two aggravating details:

  • The un-routed message measures age from issue creation (created_epoch), so a build that died 18 hours ago is reported as "after 1151h" ([Feature] Collapse managed resources under business roles in the matrix #370 was opened 19 Jun). It reads as ancient backlog noise, not as something that just broke.
  • The wrong branch also produces the wrong instruction. "The agent likely never ran" invites no action; "re-dispatch it" is what was actually needed.

Suggested direction

Don't let un-routed short-circuit liveness. Either run the Building liveness check before the state_label test, or drop the continue and make the un-routed flag skip only the drift/stale checks that genuinely need a label. Worth also measuring the un-routed age from updated_epoch, or suppressing it entirely while Status is an active phase — an issue mid-build is not un-routed.

Does it reproduce on the demo data?

Not applicable — this is CI/pipeline automation, not product code. It reproduces against the repo's own Actions history (see the two run IDs above and health issue #886).

Where does it happen? (optional)

.github/scripts/dor_reconcile.sh (dor-reconcile.yml, hourly at :17).

Did it work before? (optional)

No — the 💀 rule has been shadowed since it was introduced in #963. Its own comment says "Three builds died this way in a single day and every one of them was found by a human watching, not by this sweep"; that is still true, and this is why.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstate:out-of-pipelineNot a feature for this process — CI/tooling/test-infra/docs/meta; handled by normal dev flows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions