7.1 KiB
PR Activity, Review Attribution, and Snapshot Strategy
Status: next-stage design. No GitLink write operation is implemented here.
Goal
Provide repository owners with a general, cross-repository view of:
- all current open pull requests;
- merged and closed/rejected totals;
- state transitions since the previous assessment;
- whether a pull request received a formal review;
- whether conversation feedback came from the submitter, a reviewer, a maintainer, another participant, a bot, or a system event;
- whether review/comment content changed since the previous snapshot.
The model must not depend on a specific repository, user login, PR number, or organization role name.
Verified Read Sources
The GitLink API surfaces needed by this design are read-only:
GET /v1/{owner}/{repo}/pulls
GET /v1/{owner}/{repo}/pulls/{number}
GET /v1/{owner}/{repo}/pulls/{number}/reviews
GET /v1/{owner}/{repo}/issues/{issue_id}/journals
GET repository members when the current identity has permission
Local validation confirmed:
- list responses expose PR state, author, associated issue ID, and pagination totals;
- formal reviews expose reviewer identity, status, content, and time;
- journals expose actor identity, comment text, state events, created time, and updated time;
- repository-member lookup may return 401 for an unauthenticated read. The
implementation must degrade to
participant, not guess maintainer status.
Actor Classification
Normalize identities by stable user ID first and login second.
| Actor class | Evidence |
|---|---|
submitter |
Actor matches the PR author |
reviewer |
Actor owns a formal review or is in the assigned reviewer set |
maintainer |
Repository membership data proves a configured privileged role |
participant |
Authenticated human who is none of the above |
bot |
Explicit bot/application identity |
system |
State transition or generated event without human review content |
unknown |
Identity is incomplete |
Role precedence:
system/bot -> submitter -> formal reviewer -> maintainer -> participant -> unknown
A user can be both maintainer and reviewer. Event attribution records the most
specific event relationship (reviewer) and may retain is_maintainer=true as
an additional property.
Review Standard
Do not treat every comment as a review.
Authoritative review
A formal review object with:
status: approved | rejected | common
reviewer identity
created_at
is authoritative review evidence.
Review-like journal feedback
A journal comment is review feedback only when:
- it has non-empty human-authored content;
- it is not a creation/status/system event;
- the actor is a formal/assigned reviewer or a proven maintainer;
- the actor is not the PR submitter, unless the UI explicitly marks a self-review;
- the normalized content is not only an acknowledgement such as
LGTM,thanks, or a generated status line, unless the product policy explicitly enables acknowledgement reviews.
When member data is unavailable, a comment from an unassigned actor remains
participant_feedback, not maintainer_review.
Risk Is Separate From Review
Current workflow +repo-report risk is rule-based. A list-metadata keyword hit
is a risk hint, not proof that a reviewer found a problem.
The next-stage output should keep separate fields:
metadata_risk_hint
code_change_risk
formal_review_status
review_feedback_status
merge_readiness
Detailed code risk requires files and commits. Bulk list metadata alone must not be presented as a formal review conclusion.
Snapshot Model
Recommended local snapshot:
{
"schema_version": 1,
"repository": "owner/repo",
"generated_at": "RFC3339",
"totals": {
"open": 0,
"merged": 0,
"closed": 0
},
"pull_requests": [
{
"number": 1,
"state": "open",
"author_id": "stable-id",
"updated_at": "RFC3339",
"head_revision": "optional",
"formal_review_status": "unreviewed",
"review_fingerprint": "sha256",
"conversation_fingerprint": "sha256",
"events": []
}
]
}
Raw access tokens and private profile fields must never enter snapshots.
Content Fingerprints
Normalize review/comment content before hashing:
- normalize line endings;
- trim leading/trailing whitespace;
- collapse repeated whitespace outside code blocks;
- remove generated status-only markup;
- preserve code and semantic text;
- hash actor ID, event type, normalized content, and event time.
Store hashes and bounded summaries by default. Raw comment content should be included only in an explicitly local evidence file.
Snapshot Diff
Compare the current snapshot with --previous-snapshot and emit:
new_open_prs
newly_merged_prs
newly_closed_prs
reopened_prs
new_formal_reviews
review_status_changes
new_reviewer_feedback
edited_reviewer_feedback
submitter_responses
participant_feedback
State transitions are determined by PR number plus previous/current state, not by subtracting aggregate totals.
Fetch Strategy
Default inventory:
- paginate all PR list states;
- record exact list totals and basic identity/state fields;
- compare with the previous snapshot;
- deep-fetch reviews and journals only for new or updated PRs.
Optional full audit:
--full-review-audit
This explicitly deep-fetches every PR and may require hundreds of API calls. Use bounded concurrency, retry/backoff, and a request summary. It must remain read-only.
Planned Commands
gitlink-cli workflow +pr-activity-snapshot
gitlink-cli workflow +pr-activity-diff
gitlink-cli feishu +owner-activity-digest
The Feishu digest should show aggregate transitions and the most important changed PRs. It must link to GitLink for full comments rather than copying an unbounded conversation into a card.
Current Boundary
Implemented in the current branch:
- correct GitLink Issue and PR list filters;
- complete pagination for
workflow +repo-reportby default; - PR lifecycle totals for open, merged, and closed/rejected states;
- explicit analyzed-count labels and scope notes;
- optional read-only formal review and journal actor attribution through
workflow +repo-report --include-pr-review-audit.
The implemented audit follows the conservative review standard in this document:
- a formal
/pulls/{number}/reviewsobject marks the PR as reviewed; - journal comments from the PR submitter are counted as submitter responses, not reviews;
- journal comments from an actor who also has a formal review on the PR are counted as reviewer feedback;
- other human comments are counted as participant feedback;
- status changes and empty/generated events are counted as system events;
- a reviewed PR is marked
needs_re_reviewwhen a later submitter comment, later commit, or later PR update timestamp is newer than the latest reviewer feedback timestamp; - maintainer classification is not guessed when repository-member data is not available.
Not implemented in the current branch:
- snapshot persistence;
- member-role enrichment;
- review-content diffing;
- Feishu activity-diff cards;
- any GitLink write operation.