# Proof audit pass 1 — bare @ workspace suggestions

Issue: [#7557](https://git.cafe/pingdotgg/t3code/issues/7557). Read-only source audit at [05b697f](https://git.cafe/pingdotgg/t3code/commit/05b697f6a2012497ae790425e197fbd1fcef7de7), checkout `/home/ubuntu/wt/issue-7557`. No browser, server, tests, or product edits performed. Separate agent's modified queries.filesystem.test.ts was left untouched. Matrix below is planned evidence, not completed verification.

## Minimal setup

Use one isolated development environment with this existing checkout as the project directory and filesystem-read access granted. Use the normal dev workflow and isolated state; never point a server at live userdata. A draft composer is sufficient: no provider turn or message submission is required. Existing repository files and directories are the fixture: apps/, packages/, apps/web/src/state/queries.ts and apps/web/src/components/chat/ChatComposer.tsx. Do not add dummy files, fixture services, special menus, or product abstractions. Empty-query ranking is backend-defined with an 80-result cap: assert real existing paths, not a predetermined first row or the presence of a deep file in the initial 80. Use the typed query to select a specific source file.

## Minimal evidence matrix

Every interaction row requires a recording. Run each row at 1440px light, 1440px dark, 390px light, and 390px dark (suggested fixed heights: 900px and 844px). These are web viewport widths; 390px is not native-mobile proof. A single continuous recording per viewport/theme may cover all rows; label before/after and row boundaries. Four before and four after recordings suffice without separate clips per row.

| ID | Fixture / action | Before expectation | After acceptance | Evidence | Coverage |
| --- | --- | --- | --- | --- | --- |
| A | Empty draft, type bare @; wait for settled menu | No workspace results; empty message | Real file/folder entries from project directory; no need to type a character; icons/labels readable, drawer contained above composer | recording | 1440 light/dark; 390 light/dark |
| B | From A type apps/web/src/state/queries, then delete query back to bare @ | Typed search works; deleting loses results | Typed results include actual queries.ts; deleting returns real unfiltered entries; no stale selection applied during transition | recording | 1440 light/dark; 390 light/dark |
| C | From bare @ choose a visible real file/folder using pointer/touch; reopen, filter to queries.ts, select using keyboard navigation + Enter | Filtered selection is baseline behavior | Correct file-link insertion, menu closes, composer remains usable; no message sent. On narrow web use available input emulation for keyboard portion | recording | 1440 light/dark; 390 light/dark |
| D | Filter to a deliberately nonexistent path, clear back to @, dismiss via Escape, type ordinary text, reopen @ | No-match state works for typed queries | No-match state, recovery to entries, dismissal, and reopening all work; plain text does not keep file menu open | recording | 1440 light/dark; 390 light/dark |

Nonvisual checks to pair with recordings: focused hook test proves empty-string request with cwd/environment/limit 80; null query and missing cwd/environment remain disabled; filesystem permission gate still blocks reads; nonempty search stays enabled. Red test is being authored separately: this audit did not execute or assess its final assertions. One remote/relay connected environment smoke of A/B is useful when available; source routes through the selected environment, but no connection mode has been executed here.

## Source trace and scope

- [queries.ts](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/web/src/state/queries.ts):230–283: shared useProjectPathSearch trims and debounces 120ms, checks filesystem-read access, requires non-null environment/cwd/query, and already accepts allowEmptyQuery. Composer wrapper currently omits that option. Proposed sole production change passes `{ allowEmptyQuery: true }` to this existing call; cap remains 80.
- [useComposerMenuItems.ts](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/web/src/components/chat/useComposerMenuItems.ts):92,160: sole production web caller; path triggers pass query including empty string, other triggers pass null cwd/query. Converts actual search results into path items with searchedTarget. Thread suggestions share @ but explicitly return none for empty query in [composerThreadItems.ts](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/packages/client-runtime/src/composerThreadItems.ts), so bare-@ proof must show filesystem entries, not threads.
- [ChatComposer.tsx](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/web/src/components/chat/ChatComposer.tsx):1198,1929,3707: consumes menu data, guards selection against current environment/cwd/query, inserts serialized file link, supplies visible drawer and screen-reader status. Rendered through ChatView; CommandPalette references the composer handle rather than calling this search hook itself. No separate Settings/keybinding search implementation was found in hook references.
- [ComposerCommandMenu.tsx](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/web/src/components/chat/ComposerCommandMenu.tsx) and [ComposerCommandMenuLayer.tsx](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/web/src/components/chat/ComposerCommandMenuLayer.tsx): common light/dark menu, bounded scroll list, portal geometry based on composer rect; width/theme matrix covers this shared render path.
- [projectFilesQueryState.ts](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/web/src/components/files/projectFilesQueryState.ts): already opts into empty search. Unaffected by changing only composer wrapper.
- Desktop shell: wraps web and should inherit this hook behavior; Electron shell/IPC/layout remains UNVERIFIED. Browser recordings must not be represented as desktop verification.
- Native mobile: UNAFFECTED by this web-only call change. [mobile queries.ts](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/mobile/src/state/queries.ts):305 has a separate hook that still requires query.length > 0; native command menu uses that hook. Do not claim native bare @ is fixed.
- Providers/contracts/server: no adapter-specific execution, wire change, or new transport needed. Existing backend empty-query support has coverage in [WorkspaceEntries.test.ts](https://git.cafe/pingdotgg/t3code/blob/05b697f6a2012497ae790425e197fbd1fcef7de7/apps/server/src/workspace/WorkspaceEntries.test.ts). No provider turn needed for evidence.

## FRICTION

- Cold bare-@ search does not activate the loading label: useComposerMenuItems gates path isLoading on query.length > 0 (line 312). A transient “No matching files or folders.” can precede results; screen-reader status follows that same loading flag. Record the transition; settled results are the acceptance criterion for this narrowly scoped fix. A loading-label adjustment would be additional scope.
- Initial ordering and cap are not a promise of root-only listing; avoid asserting any specific first entry. Existing repo content supplies both real directories and searchable files.
- A denied filesystem grant is currently presented as the generic no-match state by this menu; do not use that environment as the happy-path fixture or claim this patch changes error presentation.
- No runtime evidence gathered under the read-only/no-browser instruction. Desktop, remote modes, and actual responsive/theme rendering remain unverified until the parent executes authorized verification.
