Tasks: resolve a PR's linked issues first (issue-93)
Phase 3 of 3. Derived from the locked
design.md. TDD (tdd.mode: standard): the failing test comes first for every behavioural task.
DAG
mermaid
flowchart LR
T1[T1 router tests] --> T2[T2 _pr_entity + keyword grammar]
T2 --> T3[T3 linked_issue_numbers]
T3 --> T4[T4 extract_work_items ordering]
T4 --> T5[T5 webhook integration test]
T4 --> T6[T6 gh client tests]
T6 --> T7[T7 closingIssuesReferences + downgrade]
T7 --> T8[T8 provider payload injection]
T8 --> T9[T9 poll integration test]
T5 --> T10[T10 lint/typecheck/tests]
T9 --> T10
T10 --> T11[T11 capability docs + decision]
T11 --> T12[T12 PR + briefing]Tasks
- [x] T1 — Failing router unit tests. In
cli/tests/test_routing.py: PR conversation comment (issue_commentwithissue.pull_request) →[issue, PR];closingIssuesReferenceshonoured;OWNER/REPO#N,GH-N,Fixes: #N, issue URL resolve; cross-repo reference ignored; plain issue comment unchanged; PR with no linkage →[PR]. (AC1–3, AC6, AC8) - [x] T2 —
_pr_entity+ widened_CLOSING_KEYWORD_REincli/the_loop/webhook/router.py, with the cross-repo qualifier guard. (AC1, AC3) - [x] T3 —
linked_issue_numbers(entity, owner, repo)—closingIssuesReferences→ head branch → body keywords, deduplicated, never the entity's own number. (AC2) - [x] T4 —
extract_work_items: linked issues before the PR number for every PR-shaped event; non-PR events unchanged. (AC4, AC5, AC6) - [x] T5 — Webhook integration test (
test_webhook_routing_integration.py, Gherkin + requirement link): a labelled PR's conversation comment resumes the issue's session; no new session is registered. (AC4, AC8) - [x] T6 — Failing
GhClient/provider unit tests (cli/tests/test_poller.py): the PR listing requestsclosingIssuesReferences; anUnknown JSON fielderror downgrades exactly once and is not retried on the next call; an unrelatedGhErrorstill propagates;refs()puts the linked issue first. (AC7) - [x] T7 —
GhClient.list_labeled_prs: request + parse the field, with the latched one-time downgrade and warning. (AC7) - [x] T8 — Provider plumbing:
GhItem.linked_issues,WorkItem.raw["linkedIssues"],_item_payloadinjectingclosingIssuesReferences. (AC2, AC7) - [x] T9 — Poll integration test (
test_poller_integration.py, Gherkin + requirement link): a labelled PR whose linked issue has a live session forwards the comment into it and spawns nothing. (AC4, AC8) - [x] T10 — Green gates:
ruff,pyright,pytest,markdownlintfrom the repo root (hooks.prePushparity). - [x] T11 — Docs: update
docs/capabilities/webhook-triggers.md(current behaviour + history row) and record the routing-precedence decision indocs/decisions/. - [x] T12 — PR + reviewer briefing from
skills/the-loop/templates/pr-briefing.md, phase label →loop:needs-review.