SuperAPI AI Directory

pr-evidence-comment

Testing & quality

View repository

Updated 10-15 19:58

About this skill

/pr-evidence-comment — headed acceptance → screenshots → PR comment with attached images

Turn a single headed acceptance run into evidence on the PR thatothers can open.

Why it must be uploaded, not just left as a local path

The verification artifact directory (conventionally .verification/) is usually excluded by .gitignore or .git/info/exclude —because it often contains internal information such as node id/instance type/cost, which should not go into version control. Therefore:

  • Screenshotsexist only on your machine
  • Writing .verification/2026-08-20-xxx/C1.png in a report or comment is adead link
  • In a PR comment, user-attachments is the only persistent and shared channel for these screenshots

So "upload" is not a bonus; it is a necessary condition for this workflow to hold.

Step 0 — First determine whether this change should be accepted with screenshots

Removal-type changes cannot be captured. "A certain slice was taken down", "a certain piece of dead code was removed"—screenshots can only show "it looks normal", and cannot prove "the thing is really gone". This type needsmeasurement: grep for remnants, bundle size diff, reducer key list,ls directory does not exist.

Change type Acceptance method
UI visual/interaction behavior ✅ headed screenshots
After state migration, "behavior unchanged" ✅ headed screenshots (prove it is not broken) + measurement (prove it really migrated)
Pure removal/refactor ❌ Switch to measurement, do not chase screenshots
API/data correctness ❌ Switch to curl/test output

Mixed type (common): screenshots prove "not broken", measurement proves "really removed"; you need both,do not submit only screenshots。

By /pr Step 5.5, when chained in, that step has already done the classification against the same table and obtained user authorization; here you only need to review whether the classification still holds (for example, the PR scope expanded after the gate), and there is no need to ask again.

Step 1 — Define the acceptance items and number them

List the checklist first, then open the browser, do not decide what to verify while looking—improvising will miss regression areas.

Numbering convention:

B1, B2, B3 …   未登入態(baseline)
C1, C2, C3 …   登入態(changed / core flows)
C8b            同一項的補充視角(scrolled / 展開後)

Each number corresponds toone concrete assertion, not "take a look at the page". Example:

C6-statistics-week-toggle — after clicking "Week" in the day/week/month toggle, the active state switches, the percentage updates in sync, and there isno page reload

Assertions must be written so they can be judged PASS/FAIL; something like "no page reload" is the key point (it proves local state takes effect).

Step 2 — Headed acceptance and screenshots

Storage path:<專案或知識庫>/.verification/<YYYY-MM-DD>-<slug>/<env>/ (<env> Example:staging-v2、preview-8051、hotfix)

Filename = <編號>-<kebab-描述>.png, corresponding one-to-one with the checklist in Step 1.

agent-browser open <url> --headed     # headless 起過的 session 要先 close 再重開才會套用
agent-browser snapshot -i             # 互動元素清單(~3.5K token)
agent-browser screenshot <path>

Three known elements that get stuck

Symptom Cause Solution
Clicking Radix UI Tabs does nothing role=tab + tabindex=-1,click @ref and element.click() neither triggers Full eval dispatch sequence pointerdown → mousedown → focus → pointerup → mouseup → click
Dropdown menu item is not in the snapshot Clickable item isNested without role <div> eval finds the leaf text node, walks up to the ancestor with onclick semantics, and dispatches the event directly to that div
Login form email validation failed .env.local value is double-quoted awk -F= '...' | tr -d '"' then feed it to fill

⚠️ Do not print quoted values directly into the snapshot output——I once accidentally printed the email. agent-browser masks password fields, but not email.

How to handle out-of-scope errors

If an error appears in console that is unrelated to this change (third-party components, existing API 403/400, behavior of a third-party login component),record it faithfully but do not count it as FAIL, and state the reasoning for that judgment and "recommend investigating separately." Counting out-of-scope issues toward FAIL will cost the acceptance review its adjudicative power.

Step 2.5 — Main conversation visual inspection and spot-check (the final human-eye gate before posting)

Screenshots willbe posted publicly to the PR under the user's own identity, and once posted they enter GitHub's user-attachments(deleting a comment does not necessarily retract the link). So before sending,the main conversation must actually Read several PNGs and look at them, and must not merely trust the dispatching agent's text report.

Reason: visual judgment (screenshot comparison) is the main model's responsibility, and "verification must not verify itself"——the agent that produced the screenshots cannot itself determine that the screenshots pass.

Spot-check scope:at least one from each numbered section(one from section B, one from section C), plus all of those judged FAIL/WARN.

Look at three things:

Check Why
Does the image actually capture that assertion A common failure is capturing a loading state, a blank page, or the wrong scroll position, while the agent reports PASS
Is there anything that should not be leaked email/test account/internal URL/token. agent-browser masks password fields,email it does not
Do the numbers and content match up C6-statistics-week-toggle.png does it really have a toggle switched to "week"

If any item fails → send back to Step 2 to retake, do not "post it first and deal with it later."

Step 3 — Write acceptance comment (Traditional Chinese)

## <驗收名稱>(<情境>, <日期>):PASS / PASS(附 N 個範圍外 WARN)/ FAIL

於 <base/commit> fresh-context 驗收:

**未登入態**
- B1 首頁:PASS。<觀察到什麼>
- B2 文章頁:PASS。…

**登入態**
- C1 登入 → header 不重整立即變會員態:PASS。點擊登入後 URL 未變,header 由「註冊/登入」變成頭像+通知鈴。
- …

**範圍外(不列 FAIL)**
- `<某 endpoint>` 403:判讀為帳號權限層,非本次變更引入。建議另案追查。

**量測項**(移除類必附)
- `redux/<module>/`、`saga/<module>/` 目錄已不存在;四份 root reducer 無該條目

Principles:Correspond item by item to the numbers in Step 1, one item per line with one conclusion.gh pr comment Only text is posted; images are added in Step 4.

Step 4 — Upload screenshots (★ the core of this skill; other steps can be substituted, this one cannot)

Why go through such a big detour

  1. gh Neither the CLI nor the GitHub REST API supports attaching images to comments——drag-and-drop upload is exclusive to the web UI,user-attachments the upload endpoint only accepts session auth.
  2. Cannot switch to an external image host: public exposure of a private repo's staging UI/test account screenshots is risky; and anonymous image hosts have mostly been shut down in practice (as tested in 2026-08: vgy.me closed anonymous uploads, duk.tw requires an API key, urusai.cc has no public endpoint).
  3. Cannot use agent-browser's built-in Chromium: Going through the GitHub org's Google Workspace SSO gets blocked by Google ("This browser or app may not be secure") — this is a block on automation fingerprints,headed also gets blocked。

Conclusion: only stock Chrome (genuine build) + CDP is the viable path.

Three steps

① Launch stock Chrome + separate profile + CDP port

"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --user-data-dir="$HOME/.agent-chrome-profile" \
  --remote-debugging-port=9222 --no-first-run \
  "https://github.com/login?return_to=<PR路徑>" &
  • The user logs in manuallyin this window once; the profile persists, so no re-login afterward
  • ⚠️ Chrome 136+ prohibits opening CDP on the "default profile" —— --user-data-dir pointing to a separate directory is necessary, not optional

② Connect to it

agent-browser connect 9222

③ Simulate manual attachment(classic comment form)

Target selector
The comment textarea for new comments #new_comment_field
The corresponding hidden file input #fc-new_comment_field
The file input for editing an existing comment #fc-issuecomment-<id>-body
agent-browser fill "#new_comment_field" "<Step 3 的文字>"
agent-browser upload "#fc-new_comment_field" <檔案1> <檔案2> ...

upload to the file input is equivalent to drag-and-drop: GitHub automatically uploads to user-attachments, and appends the ![...](...) markdown into the textarea。

Before submitting, you must wait for the upload to finish— eval checks the textarea value:

  • Uploading The placeholder string count is zero
  • user-attachments Link count = File count

Only submit when both hold. The submit button uses eval btn.click()(find the button in the form whose textContent is Comment ).

⚠️ Attachments are posted as the user themselves(the session is theirs) — the text direction must first be confirmed with the user, and images must first pass the visual check in Step 2.5.

Step 5 — Verify landing (not skippable)

gh pr view <num> --json comments --jq '.comments[-1].body' | grep -c "user-attachments"

The number must equal the number of uploaded files.Don't use "no errors" as success— no bad news is not good news (git status empty output is the same; it could be already committed, or it could be ignored).

Also write the screenshot list and verdict into the knowledge base session file, marking the evidence path aslocal-only。

Existing resources not to reinvent

  • Design alignment (Figma vs local):/figma-verify— division of labor with this skill: figma-verify compares "whether it was built per the design", this skill proves "the thing on the PR actually works"
  • Fact-checking:/evidence-gate(run once before finalizing the comment)
  • Live status verification:/verify-live-state
  • Opening/updating the PR itself:/pr(its Step 5.5 determines whether this skill needs to be run)