You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(mobile): name the finding on the Security Agent dismiss sheet - #9189
Evidence: demonstrated — on the local dev stack with a seeded personal Security Agent fixture, I opened the dismiss sheet from a finding detail on the Android emulator (omp36, default font scale and density) with main's component and again with this branch. The uiautomator dump of the unmodified component shows the sheet starting at REASON (y=1475 for the long-titled finding, y=1491 for the short one) with nothing above it. With this branch the same sheet renders the finding title, repository and package above the reason group: short title box (82,1502)-(998,1558), repository 1567-1604, package 1613-1650, REASON at 1733; the long title wraps to three lines (82,1502)-(998,1670) with the repository 1679-1716 and package 1725-1762 below it and REASON at 1845, so nothing is truncated and nothing overlaps.
What changed
apps/mobile/src/components/security-agent/dismiss-finding-screen.tsx renders a summary card as the first child of the form's scroll content, above the reason group:
the finding title (text-base font-medium, no numberOfLines, so a long title wraps),
the repository (repo_full_name, muted text-xs),
the package as package_name (package_ecosystem), the same formatting finding-details-panel.tsx uses for its Package row.
All three come from the useSecurityFinding result the screen already loads; no new query, no new copy, no catalog change. The header keeps the generic securityAgent.dismiss.title and the submit button keeps its label. The loading skeleton gains a block that reserves the card's height so the loading state matches the loaded one.
dismiss-finding-screen.mounted.test.tsx widens the mocked finding with the identity fields, flattens interpolated Text children when collecting rendered copy, and asserts the sheet names the title, repository and package.
Verification
Local stack on the work VM: pnpm install --frozen-lockfile, generated encryption secrets in .env.local, pnpm dev:start core nextjs cloudflare-session-ingest mobile, pnpm test:db, pnpm dev:env:mobile --host localhost, @kilocode/trpc and @kilocode/harness-sdk builds. The dev client came from the mobile-native-android-2ffd374b80d20fa89333d3c6e3fd9639025619ca CI artifact. A fake account (dismiss-sheet-e2e@example.com, seeded in kilocode_users) signed in through the app's own email OTP flow; two open personal security_findings rows were seeded, one ordinary and one with a long title, repository and package.
Flow exercised each time: findings list → tap a finding → detail → Dismiss finding → dump and screenshot. Base component: REASON at y=1475/1491 with no identity above it. Branch component: identity card present, measured as above. Selecting a reason and pressing the sheet's submit button still reaches the mutation and renders the server rejection inline (Could not complete this action…) because the local fixture has no GitHub connection to dismiss the alert on; that rejection branch is unchanged by this patch.
Checks: pnpm --filter kilo-app run typecheck, oxlint with apps/mobile/.oxlintrc.json on both files, oxfmt --check on both files, knip (check:unused), and the whole apps/mobile/src/components/security-agent/ vitest set (28 files, 396 tests) pass.
Design gate
pnpm dev:mobile:design-gate run … cannot be invoked in this repository: the tool it names is not here. Evidence gathered on this checkout (fd30e4936, main44f2b5dd6): git ls-files | grep -i design.gate → 0 files; git log --all --oneline -- '*design-gate*' → 0 commits; no dev:mobile:design-gate script in the root or apps/mobile/package.json; no apps/mobile/src/lib/design-gate probe; gh api code search over Kilo-Org/cloud and the recursive file trees of Kilo-Org/cloud and Kilo-Org/kilo-design return no such path. pnpm dev:mobile:design-gate run --link … --matrix standard therefore exits with ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL: Command "dev:mobile:design-gate" not found, which is the tool being absent, not an environment failure of the runner.
The rules the gate would check were measured on the emulator instead, per matrix cell that does not require changing the device's display size or density:
Cell
Geometry (uiautomator, px at 2.625 px/dp)
Result
base (light)
title (82,1502)-(998,1670), repository (82,1679)-(998,1716), package (82,1725)-(998,1762), reason label y=1845
inside the px-6 inset (82…998), rows do not overlap, three title lines (168 px / 56 px), nothing clipped
dark (cmd uimode night yes)
identical boxes
same pass; contrast sampled from the capture: title 13.89:1, muted meta 4.78:1
RTL (app language Arabic)
identical boxes; header back control mirrored to x=954…1080; card spans 82…998
same pass, no clipping or overlap
compact 360 dp
not run
reaching 360 dp requires changing the device's display size or density, which apps/mobile/AGENTS.md and this work item forbid
Light-mode contrast from the same sampling: title 15.71:1, muted meta 4.59:1. Every measured value clears 4.5:1 for normal text. The card is static text with no pressable and no motion, so the touch-target and motion rules do not apply; the loading state reserves the card's height (86 dp skeleton block) so the loaded card does not move anything.
iOS is not leased: the change adds text nodes to a shared component with no Platform.OS/Platform.select branch, no truncation or line-break configuration, no native code, and no keyboard or safe-area use, so the platform-specific path is the Android emulator the brief names.
Production prerequisites
None.
Proxy answers
The owner's proxy gave these answers in the owner's place.
Question: Card fields: The dismiss sheet card will show the finding title, its repository and its package. Web's equivalent dialog shows package_name • severity instead of the repository. Which fields should the mobile card carry? Answer: Title + repository + package Confidence: 0.80 · Precedent: Choose the simplest design and the smaller scope when it is enough (session a30dc8dc131a: "Simplest please"). The brief names exactly these fields.
Question: Meta labels: How should the repository and package lines be labelled? Answer: Unlabelled muted lines Confidence: 0.75 · Precedent: Do the least work with no drop in quality (session 7f3470e0ba6f: "do the least amount of work possible"). Keep similar elements consistent across surfaces: this matches the mobile finding row and adds no new copy.
Question: Header eyebrow: The finding detail screen repeats the repository as the ScreenHeader eyebrow. Should the dismiss sheet keep its header completely generic? Answer: Keep the header generic Confidence: 0.85 · Precedent: Change only what was asked (session ea803e2373e2: "just change the color"). The brief says to keep the generic header, and an eyebrow would repeat what the card shows.
bot: Android emulator (omp36, default font scale and density) against the local dev stack, fake account with two seeded personal Security Agent findings. Each capture is the dismiss sheet opened from the finding detail; the uiautomator geometry quoted in the pull request body was read from the same states.
Before (main's component): the sheet starts at the reason group, with no title, repository or package above it.
After: the sheet names the finding first — title, repository, and package_name (package_ecosystem) — then the reason group. The long title wraps to three lines instead of being truncated, and the rows below it shift down without overlap.
The dismiss sheet now renders the finding title, repository, and package_name (package_ecosystem) above the reason group using the existing useSecurityFinding data with the same non-null string fields and formatting as finding-details-panel.tsx; no bug, security, or memory-leak issue found.
Assumptions:[INFERENCE]package_name/package_ecosystem/repo_full_name are non-null strings per apps/web/src/lib/security-agent/core/types.ts:147, so the card renders the same shape as the unchanged details panel. The fixed h-[86px] skeleton only approximates the card height for long, wrapping titles — a minor cosmetic loading-state difference, not a defect.
bot: Extra matrix cells for the same sheet, measured on the Android emulator (omp36, default font scale and density) against the local dev stack with seeded fake-account findings.
Dark: cmd uimode night yes, same geometry as the light capture (title three lines, repository and package below it, reason label under the card).
RTL: app language Arabic, identical boxes with the header control mirrored; the three data lines still span the card's inner width with nothing clipped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drainWork item from the findings drainexplorer:iosFinding surfaced by the iOS explorermerge:botBot-owned review; merge when ready once readiness passes and a review approves.
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Evidence
Evidence: demonstrated — on the local dev stack with a seeded personal Security Agent fixture, I opened the dismiss sheet from a finding detail on the Android emulator (
omp36, default font scale and density) withmain's component and again with this branch. Theuiautomatordump of the unmodified component shows the sheet starting atREASON(y=1475 for the long-titled finding, y=1491 for the short one) with nothing above it. With this branch the same sheet renders the finding title, repository and package above the reason group: short title box(82,1502)-(998,1558), repository1567-1604, package1613-1650,REASONat1733; the long title wraps to three lines(82,1502)-(998,1670)with the repository1679-1716and package1725-1762below it andREASONat1845, so nothing is truncated and nothing overlaps.What changed
apps/mobile/src/components/security-agent/dismiss-finding-screen.tsxrenders a summary card as the first child of the form's scroll content, above the reason group:text-base font-medium, nonumberOfLines, so a long title wraps),repo_full_name, mutedtext-xs),package_name (package_ecosystem), the same formattingfinding-details-panel.tsxuses for its Package row.All three come from the
useSecurityFindingresult the screen already loads; no new query, no new copy, no catalog change. The header keeps the genericsecurityAgent.dismiss.titleand the submit button keeps its label. The loading skeleton gains a block that reserves the card's height so the loading state matches the loaded one.dismiss-finding-screen.mounted.test.tsxwidens the mocked finding with the identity fields, flattens interpolatedTextchildren when collecting rendered copy, and asserts the sheet names the title, repository and package.Verification
Local stack on the work VM:
pnpm install --frozen-lockfile, generated encryption secrets in.env.local,pnpm dev:start core nextjs cloudflare-session-ingest mobile,pnpm test:db,pnpm dev:env:mobile --host localhost,@kilocode/trpcand@kilocode/harness-sdkbuilds. The dev client came from themobile-native-android-2ffd374b80d20fa89333d3c6e3fd9639025619caCI artifact. A fake account (dismiss-sheet-e2e@example.com, seeded inkilocode_users) signed in through the app's own email OTP flow; two open personalsecurity_findingsrows were seeded, one ordinary and one with a long title, repository and package.Flow exercised each time: findings list → tap a finding → detail →
Dismiss finding→ dump and screenshot. Base component:REASONat y=1475/1491 with no identity above it. Branch component: identity card present, measured as above. Selecting a reason and pressing the sheet's submit button still reaches the mutation and renders the server rejection inline (Could not complete this action…) because the local fixture has no GitHub connection to dismiss the alert on; that rejection branch is unchanged by this patch.Checks:
pnpm --filter kilo-app run typecheck,oxlintwithapps/mobile/.oxlintrc.jsonon both files,oxfmt --checkon both files,knip(check:unused), and the wholeapps/mobile/src/components/security-agent/vitest set (28 files, 396 tests) pass.Design gate
pnpm dev:mobile:design-gate run …cannot be invoked in this repository: the tool it names is not here. Evidence gathered on this checkout (fd30e4936,main44f2b5dd6):git ls-files | grep -i design.gate→ 0 files;git log --all --oneline -- '*design-gate*'→ 0 commits; nodev:mobile:design-gatescript in the root orapps/mobile/package.json; noapps/mobile/src/lib/design-gateprobe;gh apicode search overKilo-Org/cloudand the recursive file trees ofKilo-Org/cloudandKilo-Org/kilo-designreturn no such path.pnpm dev:mobile:design-gate run --link … --matrix standardtherefore exits withERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL: Command "dev:mobile:design-gate" not found, which is the tool being absent, not an environment failure of the runner.The rules the gate would check were measured on the emulator instead, per matrix cell that does not require changing the device's display size or density:
uiautomator, px at 2.625 px/dp)(82,1502)-(998,1670), repository(82,1679)-(998,1716), package(82,1725)-(998,1762), reason labely=1845px-6inset (82…998), rows do not overlap, three title lines (168 px / 56 px), nothing clippedcmd uimode night yes)x=954…1080; card spans82…998apps/mobile/AGENTS.mdand this work item forbidLight-mode contrast from the same sampling: title 15.71:1, muted meta 4.59:1. Every measured value clears 4.5:1 for normal text. The card is static text with no pressable and no motion, so the touch-target and motion rules do not apply; the loading state reserves the card's height (86 dp skeleton block) so the loaded card does not move anything.
iOS is not leased: the change adds text nodes to a shared component with no
Platform.OS/Platform.selectbranch, no truncation or line-break configuration, no native code, and no keyboard or safe-area use, so the platform-specific path is the Android emulator the brief names.Production prerequisites
None.
Proxy answers
The owner's proxy gave these answers in the owner's place.
package_name • severityinstead of the repository. Which fields should the mobile card carry?Answer: Title + repository + package
Confidence: 0.80 · Precedent: Choose the simplest design and the smaller scope when it is enough (session a30dc8dc131a: "Simplest please"). The brief names exactly these fields.
Answer: Unlabelled muted lines
Confidence: 0.75 · Precedent: Do the least work with no drop in quality (session 7f3470e0ba6f: "do the least amount of work possible"). Keep similar elements consistent across surfaces: this matches the mobile finding row and adds no new copy.
ScreenHeadereyebrow. Should the dismiss sheet keep its header completely generic?Answer: Keep the header generic
Confidence: 0.85 · Precedent: Change only what was asked (session ea803e2373e2: "just change the color"). The brief says to keep the generic header, and an eyebrow would repeat what the card shows.