PR-API channel: optional collect-pr command for review comments (#5) - #17
Merged
Conversation
Implements the #5 design note: a new `collect-pr` subcommand — the package's only network-touching code, requiring an authenticated gh — records review comments and suggestion fences per document into pr_channel.jsonl with a pr_channel.json summary. Authors resolve to roster roles by GitHub login (unresolved logins recorded raw), bot reviewers are flagged rather than dropped, suggestion fences carry an extracted before/after pair, and closed-unmerged PRs contribute records — the signal squash merges and closed PRs hide from git entirely. `scan` neither reads nor writes the channel, so its determinism contract is untouched and nothing is blended into blame; joins happen downstream on document path. The three reference configs gain opt-in pr_channel blocks. Acceptance on lecture-python-programming.zh-cn: 84 review comments on 12 documents (17 human: 12 editor, 5 maintainer; 67 bot; 28 suggestions), 15 records from closed-unmerged PRs, Humphrey's engine-critique comments among them. Tests run over a stubbed API; no network in CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an optional PR-API “review comment” channel that can be collected via textstrata collect-pr <config> (using authenticated gh + REST pagination) into pr_channel.jsonl plus a pr_channel.json summary, without affecting the deterministic scan artefacts.
Changes:
- Introduces
src/textstrata/pr_channel.pyimplementing collection, roster resolution by GitHub login, bot flagging, and suggestion fence before/after extraction. - Extends config + CLI to support an opt-in
pr_channel:block and a newcollect-prsubcommand. - Adds docs and tests for the collector (explicitly no-network via a stubbed API).
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_pr_channel.py | New unit tests covering filtering, roster resolution, bot detection, suggestion extraction, and pagination concatenation. |
| src/textstrata/pr_channel.py | New collector module implementing gh api pagination parsing, comment filtering, record writing, and summary generation. |
| src/textstrata/config.py | Adds PrChannelConfig and wires pr_channel into config loading/validation. |
| src/textstrata/cli.py | Adds collect-pr subcommand and error handling for collector failures. |
| docs/method.md | Documents the PR-API channel’s purpose and output artefacts. |
| docs/configuration.md | Documents pr_channel config block and since example. |
| configs/quantecon/python-zh-cn.yml | Enables pr_channel.repo for the python zh-cn reference config. |
| configs/quantecon/programming-zh-cn.yml | Enables pr_channel.repo for the programming zh-cn reference config. |
| configs/quantecon/intro-zh-cn.yml | Enables pr_channel.repo for the intro zh-cn reference config. |
| CHANGELOG.md | Notes the new optional PR-API channel collector. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…losed-unmerged state A missing gh binary now raises GhError with an actionable message instead of an uncaught FileNotFoundError; _concat extends one list instead of copying per page; and pr_state says "closed-unmerged" rather than GitHub's raw "closed", matching the stated output contract (re-verified live: programming reads closed-unmerged 15 / merged 69). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5, implementing the design note posted there (2026-08-28) — phase 4 of the plan in #8.
What it adds
A new
textstrata collect-pr <config>subcommand, the package's only network-touching code (authenticatedgh, REST with pagination). It records one line per review comment anchored to a configured document intopr_channel.jsonl, with apr_channel.jsonsummary: PR and its state (open / merged / closed-unmerged — half the point of the channel), document and line, author login resolved to a roster role (unresolved logins recorded raw, never guessed), abotflag (Copilot and other bot reviewers are collected and separable, not dropped), suggestion fences with an extracted before (comment's diff-hunk tail) / after (fence body) pair, and reply threading.The determinism boundary holds as designed:
scanneither reads nor writes the channel — no change to any existing artefact, blame, or metric — and the collector lives in its own module the scan never imports. The channel is opt-in per edition via apr_channel: {repo: owner/name}config block (slug explicit because a checkout's remote may be a fork); the three reference configs gain theirs.Acceptance (per the design note)
Run against the real lecture-python-programming.zh-cn: 84 review comments on 12 documents — 17 human (12 editor, 5 maintainer), 67 bot, 28 suggestions — with 15 records from closed-unmerged PRs. Humphrey's engine-critique comments surface as required, 6 of his 12 document-anchored comments coming from closed-unmerged PRs that git records nowhere. The counts reconcile with QuantEcon/project-translation#22's repo-wide tallies (Copilot 80 / mmcky 16 / editor 13): the channel is document-scoped by design, so comments outside the
filesglob account for the differences.CI runs no network: the collector is tested over a stubbed API (glob and
sincefiltering, roster resolution, suggestion extraction, closed-unmerged states, pagination concatenation). Full suite green including the pinned regression.🤖 Generated with Claude Code