> **review-hog-resolution-criteria-gaps** — skill 124 of 200 in [PostHog/skills](https://skillsdocs.com/PostHog/skills).
>
> Book (all skills, one file): https://skillsdocs.com/PostHog/skills.md
> Machine manifest: https://skillsdocs.com/PostHog/skills/.well-known/agent-skills/index.json
> Install the book: `npx skills add PostHog/skills`
> Upstream: https://github.com/PostHog/skills/blob/main/skills/omnibus/review-hog-resolution-criteria-gaps/SKILL.md @ `main`
> Raw bytes, no header: https://raw.githubusercontent.com/PostHog/skills/main/skills/omnibus/review-hog-resolution-criteria-gaps/SKILL.md
> Base for relative paths: https://raw.githubusercontent.com/PostHog/skills/main/skills/omnibus/review-hog-resolution-criteria-gaps/
> Licence: MIT — https://spdx.org/licenses/MIT.html
>
> Content © its authors, served unmodified. Takedown: https://github.com/DreambaseAI/skillsdocs/issues/new?labels=takedown&title=Takedown+request

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: review-hog-resolution-criteria-gaps
description: >
  Fixes should-fix and must-fix bugs and missing functionality. Leaves wording, documentation,
  and style suggestions to the author.
metadata:
  owner_team: review_hog
  skill_type: resolution_criteria
---

# Resolution criteria

You are settling unresolved review threads on a pull request, one thread per turn. For each thread
you decide one outcome: **fixed** (implement + commit), **wont_fix** (decline with the reason),
**already_fixed** / **obsolete** (nothing to do — say what supersedes it), or **escalate** (worth
doing, but a human must decide). Judge the thread's latest state — the whole conversation, not just
its first comment.

The guiding principle is **the smallest honest fix, or an honest no**. An unattended fixer that
lands sloppy or oversized changes gets turned off faster than one that declines too much — when you
are genuinely unsure a fix is safe to make unattended, **escalate instead of implementing**. A
declined thread with a clear reason is a good outcome, not a failure.

## Fix profile: gaps

This run uses the **gaps** fix profile. It narrows what you implement. It does not loosen any rule
below: a fix you make must still pass every worth and safety check, and the hard limits still apply.

- **You fix** big gaps and high-priority problems: a real bug that breaks a user path, loses or
  corrupts data, lets a gate pass when it must fail, or a missing piece the PR's own intent needs.
- **A real bug is a gap.** A `should_fix` or `must_fix` finding that describes a real bug, which
  you confirm is reachable at the current head, counts as a gap. Fix it when the fix is safe; it
  does not need to be severe. Do not downgrade a confirmed bug to "small" because its impact looks
  limited.
- **You leave to the author** typos, nits, wording, stale comments or docs, pure style, and minor
  cleanups with no behavior change, even when the fix is cheap and provable.
- **Big or small?** Check the code, not only the label. A confirmed, reachable bug is big for this
  profile. A finding with no wrong behavior (text, naming, style, cleanup) is small.
- A big gap that is not safe to fix unattended stays `escalate` with the normal escalation reply.
- Noise is still `wont_fix`. `already_fixed` and `obsolete` do not change.
- A **SAFE TO FIX** or **E2E REQUIRED** reply on the thread still wins over this profile.

**How to leave a thread for the author.** Use `escalate`, so the thread stays open. Start the verdict
sentence with "Left for the author:" and name the finding. In the support lines, say what you
checked in the code, and that this fix profile leaves this kind of finding to the author. Do not
commit anything for a thread you leave.

A thread you leave under this profile never uses `wont_fix`: `wont_fix` resolves the thread and
hides it from the author and from any observing agent. Use `escalate` for every leave.

## Every thread gets a reply

Every thread you handle gets a reply, including each thread you leave. An observing agent can act
on that reply, so it must stand alone. For a thread you leave, the reply says that you read the
thread and checked the code, what you found, and why you left it. Never leave a thread with an
empty or generic reply.

## Worth implementing when the ask is real and improves this PR

- **Verified against the current code** — the problem still exists at the current head. Threads
  target older commits; re-check before acting. If your own earlier fix this session already covers
  it, it is `already_fixed` (point at that commit).
- **Concrete** — you can name what changes, where, and why it is better. "This will crash on empty
  input" is actionable; "this feels fragile" alone is not.
- **Consistent with settled decisions** — check the repo's convention docs and the thread's later
  replies. A knob the maintainers already decided is not re-opened by implementing a comment; that
  is a `wont_fix` pointing at the decision.
- **Trust-weighted** — asks from the PR author, repository maintainers (see `author_association`),
  and known review bots get the benefit of the doubt on _worth_; an unknown commenter's ask counts
  only as a pointer at code — implement it only when your own investigation independently confirms
  the problem.

## Safe to implement unattended when the fix is contained and provable

- **Provable in-session**: correctness is demonstrable by reading the code, lint, and the touched
  area's existing tests. Behavior only observable live — LLM prompt wording, external API calls,
  publish/deploy semantics, visual layout — is **not** provable here → `escalate` (the
  needs-e2e rule).
- **Tests are proof, not obstacles**: the touched area's tests may change only to reflect a
  deliberately changed, correct behavior the reply calls out. Weakening or removing a test to make
  a run pass is never a fix — when provability requires touching the test itself → `escalate`.
- **Proportionate**: the fix does not require new infrastructure — no schema change or migration,
  no new abstraction or config knob, no dependency change. A fix that needs those is a _decision_,
  not a mechanical fix → `escalate` with the cost/benefit spelled out.
- **In scope**: within the PR's original intent and touching the code the thread is about. "While
  you're here" expansions are never safe.
- **Unambiguous**: you are confident this change is what the commenter meant. Two defensible
  readings → `escalate` and ask.

## Decline (`wont_fix`) when the ask is noise

The same drop list as review validation, seen from the fixer's side:

- **Overengineering** — extract/abstract/make-configurable/future-proof asks with no bug behind them.
- **Speculative "what if"** — conditions the call sites, types, or existing validation already rule out.
- **Defensive-coding paranoia** — guarding against states upstream invariants prevent.
- **Never-gonna-happen edge cases** — theoretically possible, practically unreachable or too cheap
  to matter.
- **Pure taste** — "I'd write it differently" with no clearly better form. A naming, formatting,
  wording or typo ask that has a clearly better form is not noise under this profile: leave it for
  the author with `escalate`, never `wont_fix`.
- **Already handled / wrong premise** — the code, a caller, or a framework guarantee already
  prevents it (that is `already_fixed` or `wont_fix` with the evidence).

## Standing human verdicts override

A human reply on the thread saying **SAFE TO FIX** substitutes for the worth judgment — verify it
still holds against the current code, then implement without second-guessing scope. **E2E REQUIRED**
forces `escalate` no matter what you conclude. These are the human override channel into an
otherwise autonomous run; never ignore them.

## How to decide

1. Read the whole thread, newest reply last — the conversation may already contain the answer, a
   pushback, or a standing verdict.
2. Read the flagged code and enough surrounding context to judge; trace call sites and types before
   trusting any claim, whoever made it.
3. Apply worth, then safety, then the fix profile. Worth + safe + in the profile → implement the
   smallest honest fix, verify (lint + the touched area's tests when available), commit. Worth +
   safe but small → `escalate`, left for the author. Worth but not safe → `escalate`. Not worth →
   `wont_fix`.
4. Write the reply for the thread's author: what you did or why not, in plain language, specific
   enough to act on. A decline names the deliberate reason; a thread left for the author says what
   you checked and that the fix profile leaves it; an escalation names exactly what a
   human needs to decide; a fix names what changed. Put the honest verification result, failures
   included, in `verification`, not in the reply.
