Problem
Dispatch can detect PR follow-up events through PR-centric sync, but issue/board consumers do not have first-class linked PR health signals.
Right now workers have to reconstruct this themselves by:
- reading issue labels
- finding linked PRs
- checking PR review state
- checking CI/check runs
- checking merge/conflict state
That logic belongs in Dispatch so the board, queue, and worker preflight can all consume the same normalized signal.
Current behavior
Dispatch has PR follow-up sync, but it is PR-centric.
It can scan PRs for:
- comments
- CHANGES_REQUESTED reviews
- failing checks
- merge state changes
But issue queue/board items do not expose normalized linked PR health such as:
- linked PR URL
- linked PR number
- current review decision
- failing checks
- merge conflict state
- whether the issue needs follow-up
Desired behavior
For open issues with linked PRs, Dispatch should expose linked PR health metadata.
Suggested fields:
{
"linkedPrUrl": "https://github.com/org/repo/pull/123",
"linkedPrNumber": 123,
"reviewDecision": "CHANGES_REQUESTED",
"mergeStateStatus": "DIRTY",
"failingChecks": [
{
"name": "Docker Build",
"conclusion": "FAILURE"
}
],
"hasMergeConflict": true,
"needsFollowup": true,
"followupReasons": [
"changes_requested",
"failing_checks",
"merge_conflict"
]
}
Detection rulesUse current PR state, not stale historical events.Recommended logic:Use GitHub linked PR references where possible, not only title/body regex.Use current aggregate reviewDecision for requested changes.Use statusCheckRollup or check-runs/status contexts for CI failures.Treat merge conflicts as actionable when PR state clearly indicates conflict, such as CONFLICTING or DIRTY.Do not treat BLOCKED alone as actionable unless paired with failing checks or requested changes.Do not treat BEHIND alone as actionable unless paired with failing checks.Ignore draft, closed, and merged PRs for active follow-up.API/UI expectationsExpose this data in whichever layer makes the most sense:/api/issues/api/agents/{agentName}/queueboard item API/view modela dedicated linked PR health endpointThe board should be able to show that an issue in status/in-review needs attention because its linked PR has failing checks, conflicts, or requested changes.Worker preflight should be able to consume the same normalized signal instead of shelling out to gh pr view for every candidate.Acceptance criteriaIssues with linked PRs expose linked PR health metadata.Current requested-changes state is based on aggregate/current PR review decision.Failing GitHub Actions checks are detected.Merge conflicts are detected.BLOCKED alone does not trigger follow-up.BEHIND alone does not trigger follow-up.Draft/closed/merged PRs are ignored for active follow-up.Board or queue consumers can identify needsFollowup.Tests cover:requested changesfailing checksmerge conflictblocked without actionable evidencebehind without failing checksdraft PR ignoredno linked PRNotesKeep this Dispatch-native and model/harness agnostic.Do not add Saffron-specific logic.Do not depend on OpenClaw cron behavior.Do not require worker scripts to reconstruct PR health manually.
Problem
Dispatch can detect PR follow-up events through PR-centric sync, but issue/board consumers do not have first-class linked PR health signals.
Right now workers have to reconstruct this themselves by:
That logic belongs in Dispatch so the board, queue, and worker preflight can all consume the same normalized signal.
Current behavior
Dispatch has PR follow-up sync, but it is PR-centric.
It can scan PRs for:
But issue queue/board items do not expose normalized linked PR health such as:
Desired behavior
For open issues with linked PRs, Dispatch should expose linked PR health metadata.
Suggested fields:
{ "linkedPrUrl": "https://github.com/org/repo/pull/123", "linkedPrNumber": 123, "reviewDecision": "CHANGES_REQUESTED", "mergeStateStatus": "DIRTY", "failingChecks": [ { "name": "Docker Build", "conclusion": "FAILURE" } ], "hasMergeConflict": true, "needsFollowup": true, "followupReasons": [ "changes_requested", "failing_checks", "merge_conflict" ] } Detection rulesUse current PR state, not stale historical events.Recommended logic:Use GitHub linked PR references where possible, not only title/body regex.Use current aggregate reviewDecision for requested changes.Use statusCheckRollup or check-runs/status contexts for CI failures.Treat merge conflicts as actionable when PR state clearly indicates conflict, such as CONFLICTING or DIRTY.Do not treat BLOCKED alone as actionable unless paired with failing checks or requested changes.Do not treat BEHIND alone as actionable unless paired with failing checks.Ignore draft, closed, and merged PRs for active follow-up.API/UI expectationsExpose this data in whichever layer makes the most sense:/api/issues/api/agents/{agentName}/queueboard item API/view modela dedicated linked PR health endpointThe board should be able to show that an issue in status/in-review needs attention because its linked PR has failing checks, conflicts, or requested changes.Worker preflight should be able to consume the same normalized signal instead of shelling out to gh pr view for every candidate.Acceptance criteriaIssues with linked PRs expose linked PR health metadata.Current requested-changes state is based on aggregate/current PR review decision.Failing GitHub Actions checks are detected.Merge conflicts are detected.BLOCKED alone does not trigger follow-up.BEHIND alone does not trigger follow-up.Draft/closed/merged PRs are ignored for active follow-up.Board or queue consumers can identify needsFollowup.Tests cover:requested changesfailing checksmerge conflictblocked without actionable evidencebehind without failing checksdraft PR ignoredno linked PRNotesKeep this Dispatch-native and model/harness agnostic.Do not add Saffron-specific logic.Do not depend on OpenClaw cron behavior.Do not require worker scripts to reconstruct PR health manually.