Verify PR #N, does this PR fix #M, check the fix in #N, or test the candidate PR.
64
77%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/3-verify-pr-fix/SKILL.mdReview the packet, the candidate diff, and relevant tests. Live comparison against a captured baseline is optional. No edits, no merges, no pushes.
PR=$(echo "$ARGUMENTS" | sed -E 's|.*/||; s|#||g' | grep -oE '^[0-9]+' | head -1)
[ -z "$PR" ] && { echo "Invalid input: '$ARGUMENTS'. Pass a PR number or URL." >&2; exit 1; }
REPO=stickerdaniel/linkedin-mcp-server
gh pr view $PR --repo $REPO --json title,body,baseRefName,headRefName,headRepositoryOwner,mergeable,mergeStateStatus,additions,deletions,changedFiles,maintainerCanModify,statusCheckRollupExtract the linked issue number from the PR body (Closes #, Fixes #, Resolves #, or plain #N). Call it ISSUE. If multiple, ask which one is the verification target.
Read that issue's packet and comments.
This path does not need /tmp/repro-issue-$ISSUE-main.json. Absence of a local baseline limits the live branch, not the whole PR verdict. Do not create fake success or failure files.
gh pr diff $PR --repo $REPO
gh pr view $PR --repo $REPO --json files --jq '.files[].path'Hard flags (any one downgrades a clean live pass to concerns):
== "Connect", in ["Pending", "Follow"], contains("1st"), aria-label="..." with translated text. Attribute presence is the locale-independent signal..entity-result__item, .artdeco-button__text. Minimal generic selectors only (a[href*="/jobs/view/"]).PERSON_SECTIONS / COMPANY_SECTIONS entry.docs/scraping-architecture.md.A supplied capture or regression fixture can support a before-and-after claim within its scope. Protocol or startup failures are execution limits, not a pass.
This step is complete when the report can say whether the diff addresses the packet at this SHA, which audit flags apply, and whether a live comparison is still needed.
Only after an explicit yes, and only when a genuine captured baseline exists.
/2-repro-issue writes:
/tmp/repro-issue-<ISSUE>-main.json. Captured response/tmp/repro-issue-<ISSUE>-meta.json. {tool, arguments, sha}If either file is missing or empty, keep the packet-and-diff verdict. Offer the evidence-and-code path. A new live baseline requires approval.
Read sha from the meta file. Do not claim an on-main baseline merely because of the filename. Compare the same call and a sufficiently comparable account context before claiming a live fix.
if [ ! -s /tmp/repro-issue-$ISSUE-main.json ] || [ ! -s /tmp/repro-issue-$ISSUE-meta.json ]; then
echo "No captured baseline. Keep the packet-and-diff verdict. Do not check out or call the server." >&2
exit 0
fi
TOOL=$(jq -r .tool /tmp/repro-issue-$ISSUE-meta.json)
ARGS_JSON=$(jq -c .arguments /tmp/repro-issue-$ISSUE-meta.json)
BASE_SHA=$(jq -r .sha /tmp/repro-issue-$ISSUE-meta.json)
echo "Replaying: $TOOL($ARGS_JSON) from sha $BASE_SHA"Guarded checkout. Leave the user's original branch or detached SHA intact. Clean up only processes and files this run created.
if [ -n "$(git status --porcelain)" ]; then
echo "Worktree is dirty. Ask before checkout. Do not continue live comparison on a dirty tree." >&2
exit 1
fi
CURRENT_REF=$(git symbolic-ref -q --short HEAD || git rev-parse HEAD)
git fetch origin "pull/$PR/head" || { echo "git fetch for PR #$PR failed, aborting before checkout." >&2; exit 1; }
PR_SHA=$(git rev-parse FETCH_HEAD)
git checkout --detach "$PR_SHA"
cleanup_verify() {
rc=$?
trap - EXIT INT TERM
kill $SERVER_PID 2>/dev/null
wait $SERVER_PID 2>/dev/null
git checkout "$CURRENT_REF" 2>/dev/null
rm -f /tmp/verify-pr-$PR.json /tmp/verify-pr-$PR-headers /tmp/verify-pr-$PR.log /tmp/verify-pr-$PR-init.json /tmp/verify-pr-$PR-initialized.json
exit $rc
}
trap cleanup_verify EXIT INT TERMRestart the server after checkout.
PORT=8765
while lsof -nP -iTCP:$PORT -sTCP:LISTEN >/dev/null 2>&1; do PORT=$((PORT+1)); done
uv run -m linkedin_mcp_server --transport streamable-http --port $PORT --log-level INFO > /tmp/verify-pr-$PR.log 2>&1 &
SERVER_PID=$!
for i in $(seq 1 30); do
lsof -nP -iTCP:$PORT -sTCP:LISTEN >/dev/null 2>&1 && break
kill -0 $SERVER_PID 2>/dev/null || { echo "Server died during startup. Tail of /tmp/verify-pr-$PR.log:" >&2; tail -20 /tmp/verify-pr-$PR.log >&2; exit 1; }
sleep 1
done
lsof -nP -iTCP:$PORT -sTCP:LISTEN >/dev/null 2>&1 || { echo "Server never bound port $PORT after 30s" >&2; tail -20 /tmp/verify-pr-$PR.log >&2; exit 1; }
curl -s -D /tmp/verify-pr-$PR-headers -X POST http://127.0.0.1:$PORT/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"verify-pr","version":"1.0"}}}' \
> /tmp/verify-pr-$PR-init.json
SESSION_ID=$(grep -i 'Mcp-Session-Id' /tmp/verify-pr-$PR-headers | awk '{print $2}' | tr -d '\r')
[ -z "$SESSION_ID" ] && { echo "MCP initialize returned no Mcp-Session-Id. Tail of /tmp/verify-pr-$PR.log:" >&2; tail -20 /tmp/verify-pr-$PR.log >&2; kill $SERVER_PID 2>/dev/null; exit 1; }
grep -q '"error"' /tmp/verify-pr-$PR-init.json && { echo "Initialize returned a protocol error. Execution limit." >&2; cat /tmp/verify-pr-$PR-init.json >&2; kill $SERVER_PID 2>/dev/null; exit 1; }
curl -s -X POST http://127.0.0.1:$PORT/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"notifications/initialized","params":{}}' \
> /tmp/verify-pr-$PR-initialized.json
grep -q '"error"' /tmp/verify-pr-$PR-initialized.json && { echo "notifications/initialized returned a protocol error. Execution limit." >&2; cat /tmp/verify-pr-$PR-initialized.json >&2; kill $SERVER_PID 2>/dev/null; exit 1; }Capture and inspect both response bodies before tools/call. A protocol or validation error is an execution limit.
curl -s -X POST http://127.0.0.1:$PORT/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d "{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"$TOOL\",\"arguments\":$ARGS_JSON}}" \
| tee /tmp/verify-pr-$PR.json | head -200
kill $SERVER_PID 2>/dev/null; wait $SERVER_PID 2>/dev/null
diff -u /tmp/repro-issue-$ISSUE-main.json /tmp/verify-pr-$PR.json | head -200Live outcomes: fixes in this environment, fixes with concerns, does not fix in this environment, execution limit. A success here never refutes a reporter failure on a different account.
**PR #<PR>** (linked #<ISSUE>). <one-line PR title>
**Mergeable:** <CLEAN | DIRTY conflicts | BLOCKED>
**Scope:** <+X/-Y, N files>
**Packet/diff verdict:** <addresses the packet | does not address the packet | needs more evidence>
**Live verdict:** <optional, or skipped: no baseline>
**Audit flags:** <locale-dependent | DOM-class selectors | section-mapping violation | missing tests | none>
**Recommended next step:** <merge | request changes | take over via maintainer-edits | no live check needed>f4fc67d
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.