Agent Skillsnasa/fprime › post-inline-review

post-inline-review

GitHub

用于在GitHub PR中发布行内审查评论、摘要及交互线程的技能。支持建议块语法,优化首次与重跑时的API调用策略,实现增量审查和元数据就地更新。

.github/skills/post-inline-review/SKILL.md nasa/fprime

Trigger Scenarios

需要发布PR行内代码审查意见 生成或更新Agent审查摘要 处理GitHub审查线程的解决、未解决或回复操作

Install

npx skills add nasa/fprime --skill post-inline-review -g -y
More Options

Non-standard path

npx skills add https://github.com/nasa/fprime/tree/devel/.github/skills/post-inline-review -g -y

Use without installing

npx skills use nasa/fprime@post-inline-review

指定 Agent (Claude Code)

npx skills add nasa/fprime --skill post-inline-review -a claude-code -g -y

安装 repo 全部 skill

npx skills add nasa/fprime --all -g -y

预览 repo 内 skill

npx skills add nasa/fprime --list

SKILL.md

Frontmatter
{
    "name": "post-inline-review",
    "description": "Use when posting inline review comments, the per-agent summary review, or interacting with GitHub review threads (resolve, un-resolve, reply) for an F Prime PR review agent."
}

Skill: Post an inline review on a GitHub PR

Reusable procedure for any F Prime review agent that needs to post inline review comments, the per-agent summary review, or interact with GitHub review threads (resolve / un-resolve / reply).

This skill assumes:

  • An appropriately-permissioned token is exposed as ${TOKEN} in the environment (provided by whatever external trigger invoked the agent). Required scopes: read access to the repository, write access to pull-request reviews, and write access to discussions / review threads for the GraphQL mutations.
  • The agent knows the owner, repo, PR number, head commit SHA, and its own short name (matches the agent-registry.yml entry).

1. Suggestion-block syntax

GitHub renders a fenced block whose info string is exactly suggestion as a one-click "Apply suggestion" diff against the line range the comment is anchored to.

[Security] **must fix** Unbounded copy from ground argument.

Validate `len` against the destination buffer before copying. The
incoming `len` is ground-controlled and can exceed `sizeof(dst)`.

```suggestion
if (len > sizeof(dst)) { return Status::INVALID_LENGTH; }
memcpy(dst, src, len);

The suggestion block replaces the entire line range the comment is
anchored to. For multi-line replacements, anchor the comment to the
full range (`start_line` + `line`) rather than a single line.

---

## 2. Posting one review with many inline comments

A single PR review can carry many inline comments. Prefer one review
per agent run rather than many small reviews — the GitHub UI groups
them together.

**First run** — the metadata block (see §4) goes in `body` alongside
the inline `comments[]`:

```http
POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews
Authorization: Bearer ${TOKEN}
Accept: application/vnd.github+json
Content-Type: application/json

{
  "commit_id": "<head SHA>",
  "event": "COMMENT",
  "body": "<per-agent hidden metadata block — see §4>",
  "comments": [
    {
      "path": "Svc/CmdDispatcher/CmdDispatcher.cpp",
      "line": 142,
      "side": "RIGHT",
      "body": "[Security] **must fix** … \n\n<!-- fprime-agent: security-review; finding-key: abc; v1 -->"
    },
    {
      "path": "Svc/CmdDispatcher/CmdDispatcher.cpp",
      "start_line": 200,
      "line": 207,
      "start_side": "RIGHT",
      "side": "RIGHT",
      "body": "[Security] **suggestion** … \n\n```suggestion\n…\n```\n\n<!-- fprime-agent: security-review; finding-key: def; v1 -->"
    }
  ]
}

Re-run — posted only if there are new inline comments; it has an empty body (no metadata), and the metadata review is updated in place separately per §4:

{
  "commit_id": "<head SHA>",
  "event": "COMMENT",
  "body": "",
  "comments": [ ... ]
}

event: COMMENT is correct for all reviewer agents — never APPROVE and never REQUEST_CHANGES (the merge-readiness verdict is the aggregator's job, not the individual reviewer's).

The aggregator (review-summary) uses APPROVE or REQUEST_CHANGES based on its CI safety and merge readiness verdicts — see review-contract.md §10.

commit_id MUST be the head SHA the agent analyzed; this is what binds the comments to specific line positions. It is not a record of the last reviewed head — the reviewed_head line in the metadata body is (review contract §2), because a body edit leaves commit_id untouched.


3. Replying to an existing review thread

Replies post to the in-line comment that started the thread (the in_reply_to field).

POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies
Authorization: Bearer ${TOKEN}
Content-Type: application/json

{
  "body": "[Security] Fixed in <commit-sha>.\n\n<!-- fprime-agent: security-review; v1; reply-kind: resolution -->"
}

Replies are used for:

  • [<review_label>] Fixed in <sha>. after a clean resolution.

  • The Improperly resolved. reply on an un-resolved thread (see the improper-resolution body shape in the review contract §9).

  • The Disagreement — escalating. reply when contributor pushback meets the escalation criteria (review contract §11).

  • The Concur reply a reviewer posts on another agent's thread that already covers the same issue at the same site-key (review contract §6a / §9, reply-kind: concurrence).

  • The Duplicate reply the aggregator posts on a non-canonical duplicate thread during its de-duplication post-pass (review-summary.agent.md §5h, reply-kind: duplicate-close), followed by resolveReviewThread on that thread:

    [Summary] **Duplicate** — consolidated into <link to canonical thread>.
    
    <!-- fprime-review-summary; site-key: <skey>; v2; reply-kind: duplicate-close -->
    

4. Per-agent hidden metadata review

On first run, the metadata block lives in the body of the combined review described in §2 (which also carries the inline comments[] array). There is no separate metadata-only review on first run.

On re-run, any new inline comments go in a fresh review with an empty body (see §2 re-run template); if there are none, that review is not posted. The metadata is handled separately by editing the prior metadata review's body in place:

PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}
Authorization: Bearer ${TOKEN}
Content-Type: application/json

{ "body": "<!-- fprime-agent: security-review v1 -->\n<!-- reviewed_head: <head SHA> -->\n<!-- counts: ... -->\n..." }

This endpoint ("Update a review for a pull request") changes only the summary body; the review's state, commit_id, and attached inline comments are unchanged, and no notification is sent. Do not use PUT .../reviews/{review_id}/dismissals on a metadata review: GitHub only dismisses APPROVED / CHANGES_REQUESTED reviews and returns 422 Can not dismiss a commented pull request review for the COMMENTED reviews reviewers post. The review body contains only HTML-comment metadata (reviewed head, counts, verdict, run ordinal, since-last-run) — no visible summary table. The HTML marker is the de-dup key; reviewed_head is what tells the next run (and any external trigger) which head this metadata describes.

If the PUT fails with 404/403 (review not editable by this token), fall back to submitting a fresh metadata-only review (event: COMMENT, no comments[]) and let later runs take the newest marker match.


5. Resolving a review thread (GraphQL)

Two mutations, both keyed by the thread ID (NOT the comment ID). The thread ID is fetched via a GraphQL query against pullRequest.reviewThreads filtered by the comment's databaseId.

resolveReviewThread

mutation Resolve($threadId: ID!) {
  resolveReviewThread(input: { threadId: $threadId }) {
    thread { id isResolved }
  }
}

Headers:

Authorization: Bearer ${TOKEN}
Accept: application/vnd.github+json

unresolveReviewThread

mutation Unresolve($threadId: ID!) {
  unresolveReviewThread(input: { threadId: $threadId }) {
    thread { id isResolved }
  }
}

Used by the improperly-resolved row of the re-review decision table (review contract §7, phase C).

Fetching thread state

query Threads($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          id
          isResolved
          resolvedBy { login }
          comments(first: 100) {
            nodes {
              id
              databaseId
              author { login }
              body
              createdAt
            }
          }
        }
      }
      # paginate via pageInfo.endCursor / hasNextPage as needed
    }
  }
}

The agent uses this to:

  1. Index its own prior comments by finding-key (parsed out of the HTML footer).
  2. Read isResolved and resolvedBy.login (drives the maintainer-adjudicated vs. improperly-resolved decision — a core maintainer's resolution is final, re-review-state §3a-0).
  3. Read the reply chain (drives disagreement detection in review contract §11).

6. Failure modes and fallbacks

Failure Fallback
resolveReviewThread returns 403 or the token lacks the discussion-write scope Post the [<review_label>] Fixed in <sha>. reply and proceed. The thread visibly remains open but the audit trail is preserved; the own Fixed in reply makes it count as resolved in the re-review-state §4 recomputation.
unresolveReviewThread returns 403 Post the improperly-resolved reply anyway. The thread remains visibly resolved on GitHub but the reply + maintainer ping is visible inline. Increment improperly resolved regardless.
Inline-comment POST returns 422 Pull Request Review thread cannot be created on this line of the diff The line is not in the PR's diff. Re-anchor to the nearest line that is in the diff (typically the function header) and prefix the comment body with (Anchored above the offending line; the diff does not include line N.)
PUT .../reviews/{review_id} (body update) returns 404/403 Submit a fresh metadata-only review instead (§4). Never attempt /dismissals on a COMMENTED review.
Token missing entirely Fail fast. The agent emits a single line to the orchestrator: Cannot post review: TOKEN not provided. and exits. The orchestrator treats this as a FAILED reviewer per review-summary.agent.md §5.

7. Rate limits, retries, and pagination

  • Treat any 5xx response as retryable with exponential backoff (1s, 2s, 4s, 8s, give up).
  • Treat 429 and 403 with X-RateLimit-Remaining: 0 as backoff per X-RateLimit-Reset header.
  • Treat 403 without a rate-limit header as permission failure (no retry).
  • Do NOT retry 422 errors — they indicate a malformed request and retrying will produce the same error.

Secondary rate limits — abort, never retry

TOKEN is shared with other services, so tripping GitHub's secondary (abuse-detection) limit for content creation disrupts more than this review. On a 429, or a 403 whose body mentions "secondary rate limit":

  • Stop issuing content-creation calls (POST/PATCH to comments, reviews, statuses) immediately.
  • Report the abort to the orchestrator as FAILED: secondary rate limit; do not retry or wait it out.
  • Keep write bursts small in the first place: space content-creation calls out rather than firing them all at once.

Pagination discipline

  • Every list endpoint returns one page (default 30 items). Always request per_page=100 and loop until a short page is returned (REST) or hasNextPage is false (GraphQL). Silent truncation from an unpaginated call drops findings and PRs without any error.
  • For the Search API, verify the total number of items fetched equals total_count; on mismatch, log a warning — the search index may be inconsistent and results may be missing.
  • The Search API has its own 30 req/min limit; pause briefly between search pages.

8. Worked example: the full flow on one PR

  1. Read PR head SHA. Bind every subsequent call to this SHA.
  2. Fetch the agent's prior metadata review by HTML marker (review contract §6). Note its review ID, run count, reviewed_head (fallback: commit_id), and the finding-key index.
  3. Run the agent's analysis on the new head. Compute the new finding-key set; scope new below-must-fix findings to the diff since reviewed_head (re-review-state §2a).
  4. Match prior vs current per review contract §7 phase C. Build the action list: post-new, reply-fixed, resolve-thread, reply-improper, unresolve-thread, reply-disagreement, post-incorrect-fix-followup, do-nothing.
  5. Execute the action list. Compose the per-agent hidden metadata block from the resulting state.
  6. POST the umbrella review (inline comments + hidden metadata body) or, on re-run, PUT the updated metadata body onto the prior metadata review and, only if there are new inline comments, POST them as one fresh empty-body review.
  7. Return success to the orchestrator.

External references

The endpoints and mutations referenced in this skill are documented on the GitHub developer site. If a request behaves differently from what this skill describes, the GitHub documentation is authoritative; open a PR to update this skill so the next agent sees the corrected behavior.

When the API surface evolves (endpoint paths, scope requirements, response shapes), update the relevant section of this skill in the same PR that addresses the change so downstream agents inherit the new behavior automatically.

Version History

  • 736c365 Current 2026-09-23 01:43

    新增审查头标记与运行序号逻辑;重跑时元数据审查改为就地更新而非撤销重提;新增增量作用域逻辑以区分不同严重程度的发现项。

  • 7d8f579 2026-08-20 11:34

Same Skill Collection

.github/skills/agent-skill-authoring/SKILL.md
.github/skills/ai-session-report/SKILL.md
.github/skills/ai-session-summary/SKILL.md
.github/skills/ci-test-runtime-policy/SKILL.md
.github/skills/fprime-cmake-build-system/SKILL.md
.github/skills/fprime-component-design-fpp/SKILL.md
.github/skills/fprime-component-development/SKILL.md
.github/skills/fprime-component-implementation/SKILL.md
.github/skills/fprime-component-integration-test/SKILL.md
.github/skills/fprime-component-requirements/SKILL.md
.github/skills/fprime-component-unit-test/SKILL.md
.github/skills/fprime-ground-input-tracing/SKILL.md
.github/skills/fprime-hardware-input-tracing/SKILL.md
.github/skills/fprime-topology-development/SKILL.md
.github/skills/fprime-unit-testing/SKILL.md
.github/skills/jpl-design-principles/SKILL.md
.github/skills/maintainer-lookup/SKILL.md
.github/skills/pr-diff-scoping/SKILL.md
.github/skills/prompt-injection-precheck/SKILL.md
.github/skills/re-review-state/SKILL.md
.github/skills/triage-classifier/SKILL.md
.github/skills/write-system-functional-doc/SKILL.md
.github/skills/fprime-cpp-design/SKILL.md

Metadata

Files
0
Version
736c365
Hash
4362f471
Indexed
2026-08-20 11:34

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-23 06:31
浙ICP备14020137号-1