native-bug-hunt-fix
Skill2 starsChanged 35 days agoMITView on GitHub
Fix a bug found by /native-bug-hunt in the Ruby Native app and verify the fix on the Android emulator (and on the iPhone, with the user tapping) using the nd helper and dev-only debug beacon. Use whenever the user hands over a docs/bug-reports/native-*/BUG-*.md file, or asks to fix a native-app, Ruby Native, emulator or iPhone-app bug.
In this repository75 other files it gives its agents.
- acceptance-criteriaSkill
- architect-guideSkill
- architect-reviewSkill
- audit-fixerSkill
- avo-admin-expertSkill
- backend-services-expertSkill
- bug-hunt-allSkill
- bug-hunt-fixSkill
- bug-huntSkill
- build-feature-remoteSkill
- build-featureSkill
- codeSkill
- component-testSkill
- controller-expertSkill
- create-qa-documentSkill
- debugSkill
- devops-expertSkill
- execute-qaSkill
- feature-qaSkill
- fix-bug-indexSkill
- fix-honeybadgerSkill
- fix-spec-bugsSkill
- fix-system-testSkill
- frontend-expertSkill
- frontend-reviewSkill
- full-qa-fixSkill
- full-qaSkill
- full-reviewSkill
- green-ciSkill
- group-issuesSkill
- honeybadger-auditSkill
- ideateSkill
- impact-assessmentSkill
- improveSkill
- merge-mainSkill
- model-expertSkill
- model-testSkill
- native-bug-huntSkill
- page-speedSkill
- plan-questionsSkill
- planSkill
- plan-system-testsSkill
- policy-testSkill
- prdSkill
- prd-worktreeSkill
- product-questionSkill
- product-question-tldrSkill
- qa-branchSkill
- qa-testerSkill
- refactor-sweepSkill
- resolve-honeybadgerSkill
- resolve-issueSkill
- resolve-issuesSkill
- review-acceptance-criteriaSkill
- review-fixesSkill
- review-railsSkill
- rspec-test-expertSkill
- scale-reviewSkill
- service-testSkill
- settle-pr-reviewSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 3 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 52
If you can't reproduce it,: stop and tell the user what you saw, with the evidence.
- Very specific: line 82
If the children don't add up to the parent's height, the gap is usually an empty line box: an inline-block element (like button_to's form) …
- Very specific: line 87
Use $ND eval to test a hypothesis in the live page before writing code, e.g.
- Very specific: line 94
Follow /bug-hunt-fix Steps 4–6: a minimal, targeted change that follows repo conventions, then bin/standardrb --fix.
- Very specific: line 104
If you touched signals, rerun ruby_native check.
- Distinctive: line 117
after a tab switch and back
- Very specific: line 121
Web regression: check the same page in a desktop browser (Playwright, as in /bug-hunt-fix Step 10).
- Very specific: line 123
Regression test when it's expressible in a browser: add a scenario to spec/system/staff/native_app_spec.rb using its enter_native_app …
- Very specific: line 132
Run the specs you touched, then bin/standardrb.
- Distinctive: line 134
If verification fails, go back to Phase 2 with what you measured.
- Very specific: line 170
Delete tmp/native_debug/fix/ and any Playwright screenshots.
- Very specific: line 173
Don't commit, matching /bug-hunt-fix and /fix-bug-index.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Native Bug Hunt Fix
Fix one bug from a /native-bug-hunt report and prove it's fixed inside the native app, not
just in a browser. This is /bug-hunt-fix for the Ruby Native app; follow that skill's phases
(analysis → plan → implement → verify → document). This file covers what changes because the bug
lives in a WebView wrapped in native chrome.
Bug File
$ARGUMENTS
Tools
ND=.claude/skills/native-bug-hunt/scripts/nd (run it with no arguments for usage). It drives the
Android emulator through adb and talks to the dev-only debug beacon
(lib/dev/native_debug_middleware.rb + app/javascript/native_debug.js), which works on the
iPhone too:
| Need | Command |
| Run JavaScript in the live page, read state or measurements | $ND eval 'return …' (helpers: __nativeDebug.rects(sel), .dom(sel), .layout()) |
| Controls cut off by the viewport, safe-area insets, viewport height | $ND layout |
| Tap by CSS selector, or native chrome by device pixels | $ND tap '<sel>' [n] / $ND tapxy X Y (bounds from $ND native) |
| Type, keys, screenshot | $ND type, $ND key escape|back|enter, $ND shot <png> |
| Navbar, tab bar, badges, dialogs | $ND native |
| JS and console errors, layout history, request statuses | $ND log [n] |
| Reload the app from scratch | $ND relaunch |
Phase 1: Understand and Reproduce Before Touching Code
- Read the bug file. Note the Platform (Android or iPhone), app version, user, path,
reproduction steps, screenshots and any
nd logornd layoutoutput quoted in it. - Set up the app using the Prerequisites and Sign In sections of
.claude/skills/native-bug-hunt/SKILL.md: base URL,DEFAULT_ORG_SUBDOMAIN=<org-subdomain>, emulator and app installed, the user starts the tunnel (Claude can't),nd url, sign in as the report's user. - Reproduce it on the reported platform by following the report's steps through the app's UI
(tabs, list rows, navbar buttons), the way a user would.
- Record the evidence you'll compare against later:
$ND layoutnumbers,$ND nativeoutput, the offending$ND loglines, and a screenshot. Save screenshots totmp/native_debug/fix/, never todocs/bug-reports/. - For an iPhone report, ask the user for one action per message and read
$ND log/$ND evalafter each one. - Also try the other platform when you can (Android is always available to you). Knowing whether the bug is on both platforms or only one narrows the cause a lot: shared CSS and HTML versus platform-specific WebView behavior.
- Record the evidence you'll compare against later:
- If you can't reproduce it, stop and tell the user what you saw, with the evidence. Don't fix a bug you can't observe; you would have no way to verify the fix.
Phase 2: Root Cause
Investigate as in /bug-hunt-fix Steps 2–3. Native bugs usually come from one of these places:
- Native-only markup: the
native_app?branches, especially the layout (app/views/layouts/application.html.erb),app/components/staff_messaging/conversation_shell_component.*(native:flag), andapp/views/staff/conversations/_native_navbar.html.erb. - Native signals: hidden
data-native-*elements rendered through the ruby_native helpers. A mistyped or duplicated signal fails silently. Runbundle exec ruby_native check --paths=app/views,app/components. - Insets and viewport: the gem stylesheet (
stylesheet_link_tag :ruby_native) sets--ruby-native-safe-area-*and thenative-inset*classes; the app sets the viewport height, which changes when the keyboard opens.h-dvh/100vhinteract with the native tab bar and navbar differently from a browser. Compare$ND layoutnumbers rather than guessing. - Which paths render natively:
NativeMode::NATIVE_STAFF_PATHSinapp/controllers/concerns/native_mode.rb. Anything else shows Open in browser. - App config:
config/ruby_native.yml(tabs, advanced mode, appearance, linked paths). The app reads it on launch. - Navigation and redirects: in advanced mode the app pushes and pops screens, presents
/newand/editas sheets, and switches tabs for links that belong to another tab. The request sequence in$ND logshows redirect bounces (e.g.sign_in 302 → /staff/conversations).
When the page is taller than the screen (scrollHeight > innerHeight, controls under the tab
bar), find out which element adds the height before blaming insets. Measure the chain down from
main:
$ND eval 'return Array.from(document.querySelector("main").children).map(c => [c.tagName, c.className.toString().slice(0, 50), c.getBoundingClientRect().height])'.
If the children don't add up to the parent's height, the gap is usually an empty line box: an
inline-block element (like button_to's form) takes a full line-height line even when its
contents are hidden. In the first real run this was the whole bug, and its 24 px happened to equal
the Android safe area, which made insets look guilty.
Use $ND eval to test a hypothesis in the live page before writing code, e.g. apply a candidate
style and re-measure:
$ND eval 'const s = document.querySelector(".native-inset-bottom"); s.classList.replace("h-dvh", "h-full"); return __nativeDebug.layout().offscreenInteractive'.
Changes made this way last only until the next page load, so they're safe to experiment with.
Phase 3: Plan and Implement
Follow /bug-hunt-fix Steps 4–6: a minimal, targeted change that follows repo conventions, then
bin/standardrb --fix. Use /frontend-expert for real front-end work (new markup, component,
Stimulus or JS changes); a one-line wrapper or class change doesn't need it.
Native-specific rules:
- Don't break the web. Most native markup shares a component with the browser version. Keep
the fix inside the
native_app?/native:branch unless the web has the same bug, and say which you chose. - Tailwind only, with theme colors. The gem's
native-inset*classes and CSS variables are the sanctioned way to handle safe areas. - If you touched signals, rerun
ruby_native check.
Phase 4: Verify in the App
- Load the new code in the app. The WebView caches pages and assets, so run
$ND relaunch(on iOS, ask the user to swipe the app away and reopen it).bin/devrebuilds Tailwind automatically. Ruby or config changes inconfig/needbin/rails restart; ask the user before restarting the server they're running. - Repeat the reproduction steps through the UI on the reported platform, then capture the
same evidence as in Phase 1. The before and after numbers are the proof, for example
"Send button bottom 790 → 706 in a 722 px viewport;
offscreenInteractiveempty". - Check the related states:
- with the keyboard open (tap the field and re-run
$ND layout) - after a tab switch and back
- after
$ND relaunch - on the other platform, if it was affected
- with the keyboard open (tap the field and re-run
- No new errors:
$ND logshows no new JS or console errors and no failing requests. - Web regression: check the same page in a desktop browser (Playwright, as in
/bug-hunt-fixStep 10). If the change affected web markup, check that the web layout is unchanged. - Regression test when it's expressible in a browser: add a scenario to
spec/system/staff/native_app_spec.rbusing itsenter_native_apphelper (Ruby Native user agent under Playwright). Page overflow is testable there, e.g.document.documentElement.scrollHeight - window.innerHeight <= 0. Browser specs can't reproduce the native tab bar or safe-area insets, so for pure inset bugs, write down the manualnd layoutcheck in the bug file instead of a weak test. Prove the test catches the bug: set just the fix aside, run the new example and see it fail, then restore the fix. The stash stack is shared between worktrees, so use a tagged stash:git stash push -m <tag> -- <fixed files>, thengit stash apply <sha>and drop that entry. - Run the specs you touched, then
bin/standardrb.
If verification fails, go back to Phase 2 with what you measured; don't stack guesses.
Phase 5: Document and Clean Up
Append to the bug file. This is the only edit allowed in docs/bug-reports/:
---
## Fix Applied
**Date:** [date]
**Status:** VERIFIED FIXED | FIXED — iOS UNVERIFIED | NOT FIXED
### Root Cause
[One or two sentences]
### Changes Made
- [file]: [what changed]
### Verification
| Check | Android emulator | iPhone |
|---|---|---|
| Reproduced before fix | ✅ [evidence] | ✅ / not tested |
| Fixed after relaunch | ✅ [before → after numbers] | ✅ / not tested |
| Keyboard open / tab switch / relaunch | ✅ | … |
| No new JS/console errors or failed requests (`nd log`) | ✅ | … |
| Web page unchanged (Playwright) | ✅ | n/a |
| `ruby_native check` (if signals touched) | ✅ | n/a |
| Regression test | [spec:line, or "manual check: …" and why] | |Mark a platform "not tested" honestly. An iPhone-reported bug verified only on Android is FIXED — iOS UNVERIFIED until the user confirms it on the phone.
Clean up:
- Delete
tmp/native_debug/fix/and any Playwright screenshots. - Close the browser if you opened it.
- Remind the user they can stop the tunnel.
- Don't commit, matching
/bug-hunt-fixand/fix-bug-index.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

