Problem
DataMachineCode\Handlers\GitHub\GitHub::fetchIssuesOrPulls() only supports list-style filtering (state, labels, search, exclude_keywords, timeframe_limit, timeframe). There is no way to configure the fetch handler to return one specific issue or pull request by number.
This blocks any flow that needs to run an imported agent against a single, externally-supplied issue — for example the upcoming wc-static-site-agent CI workflow on chubes4/wp-site-generator#99, where workflow_dispatch supplies an issue_number and the imported flow should hydrate that exact issue as its source of truth.
The only workarounds today are:
- Inject the issue body into the AI prompt and let the fetch step return whatever the label query produces — creates two competing truths (fetch packet vs. prompt) and breaks the flow contract.
- Abuse
search with the issue title — brittle (collisions, label drift, client-side keyword match, not GitHub search).
- Bypass the fetch step entirely from a probe by calling
GitHubAbilities::getIssue() directly — moves fetch logic into the consumer and breaks the bundle's flow contract.
All three are paper-overs. The next consumer (Intelligence flows, Extra Chill event triage, any single-item targeted run) will hit the same gap.
Proposed shape
Add optional issue_number and pull_number fields to the GitHub fetch handler config. When either is set on a flow's handler_config.github:
- The handler bypasses
GitHubAbilities::listIssues() / listPulls() and calls the existing GitHubAbilities::getIssue() (line 1178) / getPullRequest() instead.
- The single returned item is normalized into the same DataPacket shape as the existing list path (
title, content, metadata.github_* fields, dedup_key of `github_<data_source>`).
- List-narrowing config (
search, exclude_keywords, timeframe_limit, timeframe, labels) is ignored in targeted mode (they cannot narrow further than one item) — log an info line if any are set alongside a number.
- `max_items` is implicitly 1.
- Existing `processed_items` dedupe still applies so reruns are idempotent (consumers can opt out by clearing the row, same as today).
- If the fetched issue/PR doesn't match the configured `state` (e.g. `open`), drop it with an info log so closed/locked items don't silently flow through.
When neither number is set, behavior is unchanged.
Settings UI
Add the two number fields to `GitHubSettings` with help text that they take precedence over list-narrowing fields.
Validation
- `issue_number` and `pull_number` are mutually exclusive — error if both set.
- `data_source` must align: `issue_number` requires `issues`; `pull_number` requires `pulls`.
Tests
Smoke test (no network) that:
- Configuring `issue_number = N` calls `getIssue` instead of `listIssues`.
- Configuring `pull_number = N` calls `getPullRequest` instead of `listPulls`.
- Mismatched `data_source` returns a clear error.
- Both numbers set returns a clear error.
- DataPacket shape matches the existing list-path shape for a single item.
Why upstream
Per the wc-site-generator/intelligence-chubes4 site rule: fix upstream first, never paper over. This gap will be hit again by any consumer that wants targeted single-item runs (CI dispatch, webhook responder, retry-by-number, scheduled per-item flows). Solving it once in DMC keeps every consumer simple.
Downstream consumer
chubes4/wp-site-generator#99 (Phase 1 CI workflow for wc-static-site-agent) is paused on this. Once this lands, that probe just sets `handler_config.github.issue_number = $issue_number` and runs the imported flow unchanged — no shim, no prompt injection.
AI assistance
- AI assistance: Yes
- Tool(s): Claude Code (Sonnet 4.5)
- Used for: Drafting this issue from the gap analysis on the wc-site-generator side.
Problem
DataMachineCode\Handlers\GitHub\GitHub::fetchIssuesOrPulls()only supports list-style filtering (state,labels,search,exclude_keywords,timeframe_limit,timeframe). There is no way to configure the fetch handler to return one specific issue or pull request by number.This blocks any flow that needs to run an imported agent against a single, externally-supplied issue — for example the upcoming
wc-static-site-agentCI workflow on chubes4/wp-site-generator#99, whereworkflow_dispatchsupplies anissue_numberand the imported flow should hydrate that exact issue as its source of truth.The only workarounds today are:
searchwith the issue title — brittle (collisions, label drift, client-side keyword match, not GitHub search).GitHubAbilities::getIssue()directly — moves fetch logic into the consumer and breaks the bundle's flow contract.All three are paper-overs. The next consumer (Intelligence flows, Extra Chill event triage, any single-item targeted run) will hit the same gap.
Proposed shape
Add optional
issue_numberandpull_numberfields to the GitHub fetch handler config. When either is set on a flow'shandler_config.github:GitHubAbilities::listIssues()/listPulls()and calls the existingGitHubAbilities::getIssue()(line 1178) /getPullRequest()instead.title,content,metadata.github_*fields,dedup_keyof `github_<data_source>`).search,exclude_keywords,timeframe_limit,timeframe,labels) is ignored in targeted mode (they cannot narrow further than one item) — log an info line if any are set alongside a number.When neither number is set, behavior is unchanged.
Settings UI
Add the two number fields to `GitHubSettings` with help text that they take precedence over list-narrowing fields.
Validation
Tests
Smoke test (no network) that:
Why upstream
Per the wc-site-generator/intelligence-chubes4 site rule: fix upstream first, never paper over. This gap will be hit again by any consumer that wants targeted single-item runs (CI dispatch, webhook responder, retry-by-number, scheduled per-item flows). Solving it once in DMC keeps every consumer simple.
Downstream consumer
chubes4/wp-site-generator#99 (Phase 1 CI workflow for wc-static-site-agent) is paused on this. Once this lands, that probe just sets `handler_config.github.issue_number = $issue_number` and runs the imported flow unchanged — no shim, no prompt injection.
AI assistance