Context
The rewrite already supervises agent work after a session exists: project registration, isolated worktrees, worker and orchestrator sessions, PR observation, lifecycle status, notifications, and dashboard visibility.
The missing product loop is issue-driven intake. A human should be able to mark an issue as ready for agent work, and the daemon should start exactly one worker session for it, preserve the issue context on the session, and let the existing PR and lifecycle machinery take over.
This issue narrows #2282 and #2283 to a single GitHub-only slice (backend + dashboard together) so it can ship ahead of multi-provider support. Linear and Jira intake are tracked separately and land as additive follow-ups once this is in.
Scope
- Daemon-side intake loop for registered projects with issue intake enabled.
- Poll the configured GitHub repo for eligible open issues.
- Define explicit eligibility through a configured label, assignee, or both — no broad/unscoped intake.
- Spawn one worker session per eligible issue, keyed by the canonical
github:<owner>/<repo>#<n> identifier so restarts cannot double-spawn.
- Build the worker prompt from the issue title, body, URL, and labels/assignees.
- Respect GitHub API rate limits: reuse the existing rate-limit-aware GitHub tracker adapter, back off per-project on a rate-limited or failed poll rather than retrying in a tight loop.
- Carry the configuration through project config, HTTP API types, and CLI (
project set-config --tracker-intake ...).
- Dashboard: a Tracker Intake section in project settings (enable, repository override, labels, assignee), inline validation, and the canonical issue id surfaced on session cards and the inspector.
- Structure the provider seam (
TrackerResolver interface) so adding Linear/Jira later is additive: a new adapter package plus a resolver-map entry, no changes to the poll/dedupe/backoff logic.
Non-goals
- No Linear or Jira adapters in this slice.
- No tracker status transitions or automatic comments — intake stays read-only toward GitHub.
- No webhook receiver.
- No dry-run matching preview, last-poll status, or pause/resume controls beyond the persisted
enabled flag.
Acceptance criteria
- Existing projects remain unaffected until they explicitly opt in.
- An eligible GitHub issue creates one worker session with its canonical issue identifier.
- Restarting the daemon does not create duplicate sessions.
- Ineligible issues are ignored; enabling intake without a label or assignee rule is rejected.
- GitHub rate-limit and auth failures back off per-project without blocking daemon startup or other projects' polling.
- Tests cover eligibility, duplicate prevention, prompt construction, failures/backoff, and the dashboard save/validation round-trip.
Supersedes/narrows #2282 and #2283 for the initial GitHub-only release.
Context
The rewrite already supervises agent work after a session exists: project registration, isolated worktrees, worker and orchestrator sessions, PR observation, lifecycle status, notifications, and dashboard visibility.
The missing product loop is issue-driven intake. A human should be able to mark an issue as ready for agent work, and the daemon should start exactly one worker session for it, preserve the issue context on the session, and let the existing PR and lifecycle machinery take over.
This issue narrows #2282 and #2283 to a single GitHub-only slice (backend + dashboard together) so it can ship ahead of multi-provider support. Linear and Jira intake are tracked separately and land as additive follow-ups once this is in.
Scope
github:<owner>/<repo>#<n>identifier so restarts cannot double-spawn.project set-config --tracker-intake ...).TrackerResolverinterface) so adding Linear/Jira later is additive: a new adapter package plus a resolver-map entry, no changes to the poll/dedupe/backoff logic.Non-goals
enabledflag.Acceptance criteria
Supersedes/narrows #2282 and #2283 for the initial GitHub-only release.