mcpbeat

Issue Gate

posthog/issue-gate

Enforce GitHub issue preflight before starting implementation work. Use when beginning a new task to match it against open issues, claim an unstarted match, create a new issue when none matches, and abort only when matching is ambiguous or in-progress work belongs to another actor.

1k tokens
context cost
the whole folder, loaded on every use
3
files
instructions only
0
copies elsewhere
how many repositories repackaged it
11
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/PostHog/duckhog --skill issue-gate

What comes with it

1 963 bytes besides the instruction
references/claude-usage.md
references/match-rubric.md

The instruction itself

7 sections, as written by the author

Issue Gate

Overview

Run issue preflight before any new implementation task. Keep GitHub Issues as the source of truth and return one decision: CREATE, CLAIM, ABORT_IN_PROGRESS, or ABORT_UNCERTAIN.

Workflow

  • Prepare inputs:
  • repository (owner/repo)
  • actor login
  • task title
  • task body file path
  • Fetch open issues using gh:
gh api --paginate "/repos/owner/repo/issues?state=open&per_page=100" | jq -s '
  add
  | [ .[]
      | select(.pull_request | not)
      | {
          number: .number,
          title: .title,
          body: (.body // ""),
          url: .html_url,
          labels: [ .labels[]?.name ],
          assignees: [ .assignees[]?.login ]
        }
    ]'
  • Run qualitative LLM matching using task + open issues and produce ISSUE_GATE_MATCH_JSON.
  • Derive and emit one decision with this contract:
{
  "decision": "CREATE|CLAIM|ABORT_IN_PROGRESS|ABORT_UNCERTAIN",
  "matched_issue_number": 123,
  "reason": "string",
  "human_action": "string"
}
  • Apply gate behavior:
  • CREATE: create issue and continue task against the created issue.
  • CLAIM: ensure actor assignment and labels, then continue task against the claimed issue. If the issue is already assigned to ACTOR, skip re-assigning.
  • ABORT_IN_PROGRESS: stop task and hand off only when the matched issue is in progress and not assigned to the current actor.
  • ABORT_UNCERTAIN: stop task and request human triage.
  • When creating the PR for the task, reference the issue in the PR description using a closing keyword (for example: Closes #$ISSUE).

LLM Matching Input (required)

Provide qualitative matching from the runtime LLM with ISSUE_GATE_MATCH_JSON:

{
  "classification": "clear|ambiguous|none",
  "matched_issue_number": 123,
  "reason": "short explanation"
}

Rules:

  • ISSUE_GATE_MATCH_JSON is required.
  • Missing or malformed ISSUE_GATE_MATCH_JSON returns ABORT_UNCERTAIN.
  • classification=clear requires a positive integer matched_issue_number.

Decision Mapping

  • classification=ambiguous -> ABORT_UNCERTAIN.
  • classification=none -> CREATE.
  • classification=clear:
  • If matched issue is in progress and assigned to someone other than ACTOR -> ABORT_IN_PROGRESS.
  • If matched issue is in progress and assigned to ACTOR -> CLAIM.
  • If matched issue is not started -> CLAIM.

In-progress signal:

  • Issue has label status:in-progress, or
  • Issue has one or more assignees.

Ownership rule:

  • If any assignee login equals ACTOR, treat issue as owned by current actor and continue (CLAIM).
  • If issue is in progress and no assignee matches ACTOR, abort (ABORT_IN_PROGRESS).

GH Commands

  • Create issue:
  • gh api -X POST "/repos/$REPO/issues" -f "title=$TASK_TITLE" -F "body=@$TASK_BODY_FILE"
  • Claim issue:
  • gh api "/repos/$REPO/issues/$ISSUE" --jq '.assignees[]?.login' | grep -Fxq "$ACTOR" || gh api -X POST "/repos/$REPO/issues/$ISSUE/assignees" -f "assignees[]=$ACTOR"
  • gh api -X POST "/repos/$REPO/issues/$ISSUE/labels" -f "labels[]=status:in-progress" || true
  • gh api -X DELETE "/repos/$REPO/issues/$ISSUE/labels/status:todo" >/dev/null 2>&1 || true

References

  • Matching rubric: references/match-rubric.md
  • Manual Claude usage: references/claude-usage.md

How to use it

Copy the folder

Take posthog/issue-gate from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.