| name | fix-comments |
| description | Resolve GitHub PR feedback end-to-end for the branch you are on. Use when you need to fetch all comments on the branch PR, evaluate whether each comment still applies, decide whether it should be addressed, implement fixes, run compile/tests with retry-on-failure, then commit and push the result. |
| metadata | {"publish":{"mode":"auto","owner":"agent","requiresEvidence":true,"verifyRemoteHead":"exact"},"required-capabilities":["git","gh"]} |
Fix Comments
Run this as a full remediation workflow for the active branch PR. Do not stop after analysis.
Inputs
- Optional: explicit scope constraints from the user (for example, "only fix blocking items").
- Optional: preferred commit message.
If no constraints are provided, default to addressing all applicable feedback.
Security
- Never print raw environment variables. Use targeted checks such as
test -n "$GITHUB_TOKEN" or trusted-tool health calls; do not run printenv, env, set, or equivalent commands that can expose secrets.
- Before posting comments or finalizing publish output, scan outgoing text for secret-like patterns (
ghp_, github_pat_, token=, password=) and stop if any are present.
Workflow
- Resolve PR and collect all comments.
- Resolve the comments helper before reading any existing comments artifact:
- Prefer
.agents/skills/fix-comments/tools/get_branch_pr_comments.py.
- Fall back to
tools/get_branch_pr_comments.py only for repositories that intentionally mirror skill helper tools into the repo root.
- If neither helper exists, stop as blocked with reason
comments_helper_missing; do not use a stale var/pr_comments/current-branch-comments.json.
- Run the resolved helper with
python3 <helper> --output var/pr_comments/current-branch-comments.json.
- If PR resolution or comment retrieval fails, stop and ask the user for a PR number/URL or GitHub credential fix. Do not continue from pre-fetched or stale comments unless the helper successfully refreshed
var/pr_comments/current-branch-comments.json in this run.
- Load
var/pr_comments/current-branch-comments.json and treat every entry in comments as input feedback.
- Build a feedback ledger before editing code.
- Create a working checklist with one row per comment:
id, type, author, url, path:line (if present), summary, still_applies, should_address, action_plan.
- Keep replies (
in_reply_to_id) tied to their parent comment to avoid duplicate work.
- Never silently drop a comment.
- Decide if each comment still applies.
- For code-line comments:
- Inspect current file state and surrounding logic, not just the old line number.
- Mark
still_applies=false only when the concern is already fixed or made irrelevant by later changes.
- For broad review/issue comments:
- Compare against current behavior, tests, and architecture constraints.
- Record a one-sentence rationale for each
still_applies=false decision.
- Decide whether each applicable comment should be addressed now.
- Default to
should_address=true for correctness, crashes, determinism, networking, security, data loss, CI stability, and test gaps.
should_address=false is allowed only when:
- It conflicts with explicit user direction, or
- It requires product/design decisions outside current scope.
- Record rationale for each skipped item and keep the skipped list in final output.
- Implement fixes with the smallest safe change.
- Process one actionable item at a time.
- Prefer root-cause fixes over cosmetic edits.
- Add or update tests whenever behavior changes.
- Re-check adjacent comments after each fix to collapse duplicates.
- Run compile/tests and retry until green.
- Follow repo AGENTS guidance for local Unreal validation:
- Compile only if platform build entrypoint and toolchain exist.
- Run targeted automation tests when
UnrealEditor-Cmd is available.
- If compilation/tests fail:
- Read logs,
- Fix the failures,
- Re-run compile/tests.
- Repeat until the touched scope is passing locally, or until blocked by missing environment prerequisites. If blocked, report exact blocker.
- Finalize and push.
- Ensure every comment is classified in the ledger (
addressed, not-applicable, or deferred-with-reason).
- Run a final
git status review.
- If tracked or untracked code/documentation changes exist outside ignored artifacts, commit with a clear message (default:
Address PR feedback for #<number>).
- Push the current branch after committing.
- If there was nothing to commit, still prove the current branch is published: verify the exact local
HEAD SHA is visible on the remote PR branch using gh pr view, git ls-remote, or an equivalent GitHub connector path.
- After the exact pushed/no-op head is verified, group review comments by
thread_id. Resolve a current GitHub review thread only when every
non-outdated comment in that thread has a ledger disposition of addressed or
not-applicable. If any comment in the thread is deferred, unclassified, or
still applicable, leave the entire thread unresolved. The refreshed comments
artifact exposes the GraphQL node as thread_id; resolve eligible threads with
GitHub's resolveReviewThread mutation. Never resolve an outdated thread. If a
fully handled current thread cannot be resolved, stop as blocked with reason
publish_unavailable; an unresolved current thread remains an authoritative
merge blocker.
gh api graphql \
-f threadId="$THREAD_ID" \
-f query='mutation($threadId:ID!){resolveReviewThread(input:{threadId:$threadId}){thread{isResolved}}}'
- Refresh
var/pr_comments/current-branch-comments.json after resolving threads. Do not report success while any handled, non-outdated review comment still has thread_resolved=false.
- After any push or no-op verification, re-check that the remote PR branch head SHA equals local
HEAD by writing canonical evidence through the shared helper:
python3 .agents/skills/_shared/publish_evidence.py write-pushed \
--skill-id fix-comments \
--repo "$REPO" \
--branch "$BRANCH"
If there was no commit to push, use:
python3 .agents/skills/_shared/publish_evidence.py write-no-op \
--skill-id fix-comments \
--repo "$REPO" \
--branch "$BRANCH"
If push or remote verification is unavailable, write blocked evidence and
stop as blocked with reason publish_unavailable:
python3 .agents/skills/_shared/publish_evidence.py write-blocked \
--skill-id fix-comments \
--repo "$REPO" \
--branch "$BRANCH" \
--reason publish_unavailable
Do not report success.
- When fix-comments is delegated by pr-resolver and publication is unavailable, also ensure
var/pr_resolver/result.json reflects status=blocked, merge_outcome=blocked, and mergeAutomationDisposition=manual_review so the parent resolver cannot report a stale merge-ready result.
Output
Provide a concise report with:
- PR number and URL.
- Count summary: total comments, addressed, not applicable, deferred.
- Per-comment disposition (comment URL + decision + short rationale).
- Files changed.
- Compile/test commands run and their final status.
- Commit hash or verified no-op
HEAD hash, plus pushed/verified branch.
Notes
- Use
tools/get_branch_pr_comments.py as the default retrieval path; it wraps tools/get_pr_comments.py.
- If retrieval needs customization (repo/token/review-body filtering), pass through the corresponding flags supported by
tools/get_branch_pr_comments.py.
- Do not claim completion if compile/tests are still failing.
Comment Resolution Ledger
After classifying all comments, write the ledger to artifacts/pr_resolver_addressed_comments.json (this is the path the pr-resolver snapshot reads).
IMPORTANT — always write this file using run_command with cat, never with write_to_file.
This file is typically open in the user's editor. Using write_to_file triggers a VS Code
external-modification dialog that causes the tool pipeline to stall indefinitely until cancelled.
Use the shell cat heredoc form instead:
cat > artifacts/pr_resolver_addressed_comments.json << 'EOF'
[...]
EOF
The format is a JSON array of objects:
[
{
"id": 12345678,
"disposition": "addressed",
"rationale": "Removed unused import in commit abc1234."
},
{
"id": 87654321,
"disposition": "not-applicable",
"rationale": "Informational summary from bot, no action needed."
}
]
Accepted disposition values: addressed, not-applicable. The id field must match the comment's numeric id from the comments JSON. Alternatively, comment_id and status field names are also accepted for backwards compatibility.