Skip to content

Targeted dispatch can drift into scheduled backlog triage when bound issues are integrity-filtered on public repos #21784

@samuelkahessay

Description

@samuelkahessay

Context

Observed on 2026-03-19 while retesting repo-assist after the #033 expression fix had already shipped.

This is not the earlier prompt-rendering bug from #21501 / #21624.

On the latest retest with gh-aw v0.62.0, the activation prompt correctly rendered:

  • Take heed of **instructions**: ""
  • If 14 is non-empty, this run was dispatched for a specific issue and is bound to issue #14.

So the workflow was correctly compiled and correctly bound to issue #14.

The run still finished success with no PR, but the failure mode was:

  1. the agent ignored the targeted-dispatch instruction to fetch issue #14 directly
  2. it scanned the backlog with list_issues
  3. public-repo automatic integrity filtering removed pipeline issues, including #14
  4. the agent concluded there were no open implementation issues
  5. it switched into what it called "Scheduled Mode"
  6. it triaged unrelated [aw] workflow-failure issues (#22, #20, #18)
  7. it emitted noop: Pipeline complete - No open issues or PRs to implement...

That means a targeted dispatch bound to a real open issue can silently succeed while doing unrelated work.

Problem

For public repositories, gh-aw automatically applies min-integrity: approved when no explicit GitHub guard policy is configured.

Relevant implementation/docs:

  • pkg/workflow/mcp_github_config.go:413-422 says public repos automatically get min-integrity: approved
  • docs/src/content/docs/reference/github-tools.md:106-113 defines integrity from author_association, with:
    • approved = OWNER, MEMBER, COLLABORATOR
    • none = FIRST_TIMER, NONE

The bound issue in the failing run was:

  • issue #14
  • repo: samuelkahessay/team-standup-tracker
  • user: prd-to-prod-pipeline[bot]
  • author_association: NONE

Under the current automatic guard model, that issue is filtered.

That filtering may be intentional under the trust model. The bug reported here is narrower:

  • targeted dispatch mode was present in the prompt
  • the agent still fell back to backlog scanning
  • the bound issue was filtered out of that backlog scan
  • the run then behaved as if it were an unbound scheduled run

The user-visible failure is not just filtered visibility. It is that a targeted run can lose its target and still exit success.

Why this is a bug

If issue_number=<N> was supplied on workflow_dispatch, that run should remain bound to #N.

It should not:

  1. substitute a backlog scan for the bound issue
  2. reclassify itself as "Scheduled Mode"
  3. triage unrelated issues
  4. emit a successful noop claiming there is no implementation work

If the bound issue is unreadable because of integrity policy, the run should fail explicitly or surface a clear integrity-filtered status for the bound issue. It should not drift into unrelated work.

Location

The observed behavior spans two layers:

  1. Automatic public-repo guard policy

    • pkg/workflow/mcp_github_config.go:413-422
    • public repos get automatic min-integrity: approved
  2. Targeted-dispatch execution path

    • the prompt clearly instructs targeted mode
    • the agent still called list_issues and treated the run like general backlog processing
    • once list_issues returned [], the run moved into unrelated [aw] triage and noop success

There are likely two related product gaps here:

  • integrity-filtered same-repo automation issues disappear from normal issue listing
  • targeted dispatch is not hardened against that disappearance

Reproduction

  1. Use a public repository.
  2. Enable GitHub tools without explicitly setting tools.github.min-integrity or tools.github.lockdown.
  3. Let gh-aw auto-apply min-integrity: approved.
  4. Create an implementation issue through repo automation so the resulting issue author has GitHub author_association: NONE.
  5. Run a gh-aw implementation workflow through targeted workflow_dispatch with issue_number=<that-issue>.
  6. Observe:
    • the prompt says the run is bound to that issue
    • the agent still calls list_issues
    • the bound issue is filtered from that result
    • the agent concludes there are no open implementation issues
    • the run completes successfully without touching the bound issue

Observed concrete repro:

  1. Public repo: samuelkahessay/team-standup-tracker
  2. Open issue #14, authored by prd-to-prod-pipeline[bot], author_association: NONE
  3. Compile workflows with gh-aw v0.62.0
  4. Dispatch Pipeline Repo Assist via workflow_dispatch with issue_number=14
  5. The prompt still says the run is bound to #14
  6. The agent calls list_issues and gets []
  7. The gateway logs show #14 was filtered from list_issues
  8. The agent declares there are no open implementation issues
  9. The run triages unrelated [aw] issues and emits noop success

Expected behavior

A targeted dispatch bound to an existing issue should not silently succeed with unrelated work.

Expected outcomes:

  • the bound issue is fetched directly and handled
  • or, if integrity policy blocks it, the run fails explicitly with a message like:
    • issue #14 exists but is filtered by min-integrity=approved (author_association: NONE)

It should never degrade into scheduled backlog processing for unrelated issues.

Evidence

Latest failing run: 23293758712

  • Date: 2026-03-19
  • Workflow: Pipeline Repo Assist
  • Event: workflow_dispatch
  • Branch: main
  • Head SHA: 40122dc96083be9779bcc5b48e1ec83bd09ec2b5
  • Workflow compiler version: gh-aw v0.62.0
  • Runtime MCP gateway: v0.1.19
  • Runtime GitHub MCP server: v0.32.0

The prompt was correctly bound to issue #14

From the activation and agent prompt artifacts:

  • Take heed of **instructions**: ""
  • If 14 is non-empty, this run was dispatched for a specific issue and is bound to issue #14.

So this was not an unbound scheduled run.

The agent still scanned the backlog

From agent-stdio.log:

  • list_issues -> []
  • agent reasoning: Good! The Next.js application exists. Now let me check for open PRs and [aw] issues:

It then proceeded to:

  • list_pull_requests
  • search_issues repo:samuelkahessay/team-standup-tracker is:open label:agentic-workflows
  • actions_get / actions_list for unrelated failed workflows

That is not consistent with the prompt instruction:

  • Treat issue #14 as the only candidate for Task 1 in this run.
  • Fetch that issue directly instead of scanning the backlog to choose a task.

The bound issue was filtered out of list_issues

From mcp-logs/github.log:

  • DIFC-FILTERED on list_issues for issue:samuelkahessay/team-standup-tracker#14
  • reason: lower integrity than the agent requires

The same log shows many automation-authored pipeline issues being filtered in the same call.

The bound issue was live during investigation:

  • issue #14 was OPEN
  • title: [Pipeline] Create database schema and initialization
  • user: prd-to-prod-pipeline[bot]
  • author_association: NONE

The run reclassified itself as scheduled mode

From agent-stdio.log and repo-memory output:

  • This appears to be a fully complete PRD run.
  • I should ... Call noop to signal completion since there's no implementation work to do
  • it wrote run-45-status.md with:
    • Mode: Scheduled (no targeted issue)
    • Open Issues: 0 pipeline issues
    • Issue #22, #20, #18 triage summary

So the run lost the dispatch binding entirely, even though the prompt contained it.

Workflow outcome was misleading

The run finished success and emitted:

Pipeline complete - No open issues or PRs to implement. Triaged 3 [aw] infrastructure workflow failures (all non-blocking quality/monitoring tools). Application fully implemented on main.

No PR was created for issue #14.

Earlier related run on v0.61.2

An earlier run on the same repo after the #033 fix shipped, 23292688284, showed a closely related symptom:

  • the prompt was also correctly bound to #14
  • the backend fetched issue_read(#14)
  • DIFC filtered the result to []
  • the agent concluded the issue was missing and emitted noop success

So the underlying integrity-filtering problem remained after #033, and the latest v0.62.0 run still fails, now via a broader targeted-dispatch control-flow bug.

Proposed fix

The minimum product fix is to harden targeted dispatch:

  1. When issue_number is supplied, force a direct bound-issue read before any backlog scan

    • do not let the run substitute list_issues candidate selection for the bound issue
  2. If the bound issue is filtered by integrity policy, fail explicitly

    • do not allow fallback to "scheduled mode"
    • do not allow fallback to unrelated issue triage
    • surface a clear error for the bound issue instead of []
  3. Do not allow successful noop completion when a targeted issue was never successfully evaluated

    • targeted dispatch should be all-or-nothing with respect to the bound issue
  4. Add regression coverage

    • public repo
    • automatic min-integrity: approved
    • issue authored by same-repo automation with author_association: NONE
    • targeted workflow_dispatch
    • assert the run does not drift into backlog or scheduled-mode behavior

Optional product decision, separate from the core bug:

  1. Revisit whether same-repo automation-authored issues should remain readable under the automatic public-repo guard
    • that may help gh-aw's own issue-driven automation model
    • but the targeted-dispatch correctness bug should be fixable even if the trust model stays as-is

Environment

  • Latest verified repro version: gh-aw v0.62.0
  • Latest observed run: 23293758712
  • Earlier supporting run: 23292688284
  • Repository visibility: public
  • Target repo: samuelkahessay/team-standup-tracker
  • Runtime GitHub MCP server: v0.32.0
  • Runtime MCP gateway: v0.1.19
  • Affected object type: automation-authored public-repo issues with GitHub author_association: NONE

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions