Brings the read-side surface up to parity with the legacy TS impl's
useful read methods. Closes a gap flagged during scope review.
Port additions:
- List(ctx, repo, filter) ([]Issue, error)
- Preflight(ctx) error
Domain additions: TrackerRepo, ListStateFilter (open/closed/""=all),
ListFilter (State, Labels, Assignee, Limit).
GitHub adapter:
- List hits GET /repos/{o}/{r}/issues with query-encoded filter.
Defaults: state=all, per_page=30; per_page is capped at 100.
PRs are filtered out client-side (GitHub conflates them with
issues on that endpoint).
- Preflight hits GET /user. Success is cached for the Tracker's
lifetime via sync.Mutex + bool; failures are intentionally NOT
cached so a transient startup glitch is recoverable.
- New ErrAuthFailed sentinel. classifyError now maps 401, and 403
without rate-limit signals, to ErrAuthFailed instead of an opaque
error — so Preflight callers can distinguish bad-token from other
failures.
Pagination beyond the first page is intentionally out of scope for v1
(see doc.go); the observer/polling work in #35 will own that.
Tests: 43 pass (was 25). Adds Preflight cache + recovery, List query
encoding, PR filtering, repo parser rejection, and ErrAuthFailed
classification.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Scope correction: mirroring agent lifecycle onto the tracker (status
comments, label/state updates) is not wanted in the current rewrite.
That work is now tracked as issue #40 and will land once we decide on
the opt-out knob, label setup, and Linear's workflow-state fit.
Removes from the port and the GitHub adapter:
- Comment(ctx, id, body) and ErrEmptyBody
- Transition(ctx, id, state) and ErrUnknownState
- planForState / transitionPlan and the forward state mapping
- reasonComplete constant (only the Get reverse mapping is kept)
- 11 tests + the transitionCall normalization helpers
Kept (still load-bearing for Get):
- All 5 NormalizedIssueState values — Get reports them faithfully
when a repo carries the in-progress / in-review labels.
- The reverse mapping in mapStateFromGitHub.
- RateLimitError with ResetAt + RetryAfter (#35 will use it).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Reference implementation; GitLab and Linear follow in separate PRs.
Issue observer loop (poll + ApplyTrackerFacts) is deferred to #35.
Three-layer split mirrors the SCM layout adil is landing in PR #28:
- domain/tracker.go — value types (TrackerProvider, TrackerID,
NormalizedIssueState, Issue)
- ports/tracker.go — the Tracker interface
- adapters/tracker/github/ — REST-backed adapter
v1 is write-mostly: Get, Comment, Transition. No cache, no inflight
dedup, no polling. State mapping is documented in the package doc and
exercised by table-driven tests against an httptest fake — no real
GitHub traffic from CI.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>