diff --git a/.ai/architecture.md b/.ai/architecture.md
new file mode 100644
index 0000000..64edcb8
--- /dev/null
+++ b/.ai/architecture.md
@@ -0,0 +1,103 @@
+# Architecture
+
+## Process Model
+
+ImEX RPS has two main runtimes:
+
+- Electron main process: window lifecycle, native menus, file system access, estimate decoding, file watching/scanning, audit file dialogs, updater, app-level settings, analytics, and IPC.
+- React renderer process: UI, routing, Redux state, Apollo GraphQL operations, Firebase auth, and renderer-side IPC listeners.
+
+The renderer does not get Node integration. The preload script exposes a controlled bridge:
+
+- `window.ipcRenderer.send(channel, data)`
+- `window.ipcRenderer.on(channel, handler)`
+- `window.ipcRenderer.invoke(channel, data)`
+- `window.ipcRenderer.removeAllListeners(...)`
+- `window.logger.*`
+
+## Entrypoints
+
+Electron:
+
+- `electron/main.js` decides whether to run the source main file or bundled `dist-electron/main.cjs`.
+- `electron/main-src.js` is the main source file.
+- `electron/preload.js` decides whether to run the source preload or bundled `dist-electron/preload.cjs`.
+- `electron/preload-src.js` exposes IPC/logger bridges.
+- `scripts/build-electron.mjs` bundles main/preload outputs.
+
+Renderer:
+
+- `src/index.jsx` initializes Sentry renderer, Redux Provider, `MemoryRouter`, `PersistGate`, and ``.
+- `src/App/App.jsx` initializes Apollo, AntD context/theme, auth session check, IPC side effects, and authorized/unauthorized routing.
+- `src/components/pages/routes/routes.page.jsx` renders the main app shell and routes.
+
+## Routing
+
+Routes are memory-router routes because this is an Electron app:
+
+- `/` Jobs
+- `/settings` Settings
+- `/reporting` Reporting
+- `/audit` Audit
+- `/scan` Scan
+- `/admin` Admin
+
+The app shell includes the side menu, notifications modal, release notes, and update manager.
+
+## Redux Shape
+
+Store setup:
+
+- `src/redux/store.js`
+- Redux core `legacy_createStore`
+- Saga middleware
+- Redux logger in development
+- Redux DevTools compose if present
+- redux-persist wrapper with all active reducers currently blacklisted
+
+Reducers:
+
+- `application`: watcher status, watched paths, selected job id, selected target percent, settings, update state, release notes, estimate scrubber results.
+- `user`: current user, bodyshop, targets, fingerprint, auth errors, notifications, dark mode.
+- `reporting`: report date range, report rows, scorecard, audit data/errors/loading, excluded ids, cached jobs.
+- `scan`: scan loading state, last scanned, estimate list.
+
+Sagas:
+
+- `applicationSagas`
+- `userSagas`
+- `reportingSagas`
+- `scanSagas`
+
+## Data Flow for Estimate Import
+
+1. User configures `filePaths` in settings.
+2. Electron store persists those paths.
+3. `electron/file-watcher/file-watcher.js` watches paths with chokidar.
+4. New/changed estimate files are decoded by `electron/decoder/decoder.js`.
+5. Main process sends decoded payloads over IPC.
+6. Renderer `src/ipc/ipc-renderer-handler.js` receives decoded estimates.
+7. Renderer GraphQL helper `UpsertEstimate` writes jobs/joblines to Hasura.
+8. Jobs UI queries data back through Apollo.
+
+## Data Flow for Job Details
+
+1. A list item dispatches selected job id to Redux `application`.
+2. `jobs-detail.organism.jsx` debounces selected id briefly to avoid rendering a stale/partial left panel.
+3. Apollo queries `QUERY_JOB_BY_PK`.
+4. Detail subcomponents render job metadata, joblines, targets, group controls, claims clerk, estimate scrubber, and other actions.
+
+## IPC Contract
+
+IPC channel names live in `src/ipc.types.json`, imported by:
+
+- `src/ipc.types.js` for ESM renderer code.
+- `src/ipc.types.commonjs.js` for CommonJS Electron code.
+
+When adding IPC:
+
+- Add channel names to `src/ipc.types.json`.
+- Register main handlers in the relevant Electron module.
+- Register renderer listeners in `src/ipc/ipc-renderer-handler.js` or a local component effect.
+- Keep handlers idempotent when possible; repeated imports/listeners can create duplicate events.
+
diff --git a/.ai/data-graphql-hasura.md b/.ai/data-graphql-hasura.md
new file mode 100644
index 0000000..b9b3e84
--- /dev/null
+++ b/.ai/data-graphql-hasura.md
@@ -0,0 +1,113 @@
+# Data, GraphQL, Hasura, and Auth Guide
+
+## GraphQL Client
+
+Apollo setup lives in `src/graphql/GraphQLClient.js`.
+
+Links:
+
+- `HttpLink` uses `import.meta.env.VITE_APP_GRAPHQL_ENDPOINT`.
+- `authLink` reads Firebase current user token and attaches `Authorization: Bearer `.
+- `RetryLink` retries transient failures.
+- `onError` logs GraphQL/network errors.
+- `SentryLink` records Apollo operations/errors.
+- `apollo-link-logger` is included in development.
+
+Default options:
+
+- `query.fetchPolicy = "network-only"`
+- `watchQuery.fetchPolicy = "network-only"`
+- `connectToDevTools` enabled outside production
+
+Cache:
+
+- `Query.jobs` uses offset merge policy.
+- `Query.search_jobs` uses offset merge policy.
+
+This avoids Apollo "Cache data may be lost when replacing the jobs field" warnings during pagination.
+
+## GraphQL Operation Files
+
+- `src/graphql/jobs.queries.js`: job insert, latest pagination, search pagination, job by id, job by claim number, close date lookup, update/delete, estimate scrubber query.
+- `src/graphql/joblines.queries.js`: jobline update.
+- `src/graphql/bodyshop.queries.js`: current bodyshop, shop update, notifications.
+- `src/graphql/user.queries.js`: user upsert/login association.
+- `src/graphql/reporting.queries.js`: report data.
+- `src/graphql/notification.queries.js`: accept notification.
+- `src/graphql/veh_group.queries.js`: vehicle group lookup.
+
+## Hasura Layout
+
+Hasura project files:
+
+- `hasura/config.yaml`
+- `hasura/config.yaml.prod`
+- `hasura/metadata/`
+- `hasura/migrations/default/`
+- `hasura/migrations_backup/`
+
+Important metadata:
+
+- `hasura/metadata/databases/default/tables/`
+- `hasura/metadata/databases/default/functions/public_search_jobs.yaml`
+
+Important tables:
+
+- `users`
+- `bodyshops`
+- `associations`
+- `jobs`
+- `joblines`
+- `targets`
+- `veh_groups`
+- `groupings`
+- `notifications`
+
+Important function:
+
+- `search_jobs`
+
+## Core Relationships
+
+- `users.email` links to `associations.email`.
+- `associations.bodyshopid` links users to bodyshops.
+- `jobs.bodyshopid` links jobs to bodyshops.
+- `joblines.jobid` links joblines to jobs.
+- Notifications can target a bodyshop.
+
+## Schema Evolution Notes
+
+The `jobs` and `joblines` schema has grown significantly over time. Do not assume the original create-table migrations show the current shape.
+
+Recent-ish/important fields include:
+
+- `jobs`: `close_date`, `loss_date`, `v_age`, `v_mileage`, `group`, `group_verified`, `requires_reimport`, `ins_rule_set`-related usage through bodyshop settings, owner fields, impact fields, totals/rates JSON, vehicle stage, theft/tlos/insp fields, supplement/betterment amounts, ES fields.
+- `joblines`: `line_no`, `db_ref`, `price_diff`, `price_diff_pc`, `ignore`, ADAS/claims clerk/ruleset fields, labor/part flags, tax/cert/glass flags, line refs, modified labor/price fields.
+- `bodyshops`: `accepted_ins_co`, `targets`, `groups`, `features`, `channel`, `phone`, `zip_post`, `es_api_key`, `mpi_count_quantity`, `carfax_exclude`, `ins_rule_set`.
+
+Use Hasura metadata and current GraphQL query selections to confirm exact field names before changing queries or migrations.
+
+## Authentication
+
+Firebase auth utilities live in `src/firebase/firebase.utils.js`.
+
+Renderer startup:
+
+1. `src/index.jsx` mounts Redux and App.
+2. `src/App/App.jsx` dispatches `checkUserSession`.
+3. User sagas validate/load user state.
+4. Apollo auth link uses the current Firebase token for GraphQL.
+
+If a user has no shop access, `RoutesPage` renders a "No shop access" error result.
+
+## Data Import Boundary
+
+Electron main decodes local DBF files. Renderer writes decoded results to Hasura. This means import bugs may straddle:
+
+- DBF decoding in `electron/decoder/decoder.js`.
+- IPC payloads in `src/ipc/ipc-renderer-handler.js`.
+- GraphQL upsert helpers in `src/ipc/ipc-estimate-utils.js`.
+- Hasura insert/update permissions and constraints.
+
+When debugging import issues, inspect all four layers.
+
diff --git a/.ai/domain-glossary.md b/.ai/domain-glossary.md
new file mode 100644
index 0000000..49528c2
--- /dev/null
+++ b/.ai/domain-glossary.md
@@ -0,0 +1,111 @@
+# Domain Glossary
+
+This glossary captures terms that appear in code, database fields, and UI.
+
+## Business Terms
+
+- RPS: Repair Performance System, the desktop app/product.
+- Bodyshop: A repair shop/account using the app.
+- Association: Link between a user email and a bodyshop.
+- Job: A repair claim/estimate record.
+- Jobline: A line item within a repair estimate.
+- Claim number / `clm_no`: Claim identifier used for lookup/search.
+- RO number / `ro_number`: Repair order number.
+- Insurer / `ins_co_nm`: Insurance company name on a job.
+- Accepted insurers / `accepted_ins_co`: Shop-specific list of insurers to accept/import.
+- Close date: Claim close date, used in reporting and ruleset selection.
+- Loss date: Date of loss, used by job queries and reporting.
+- Vehicle group / `group`: Group assignment based on vehicle make/type/age and configured rules.
+- Target: Target percentage used in RPS calculations.
+- Grouping: Hasura data that maps vehicle make/type/date ranges to groups.
+- Group verified: User/shop-confirmed group assignment.
+- Requires reimport: Flag indicating a job should be reimported because decoded data or rules changed.
+
+## Estimate/File Terms
+
+- EMS: Estimate Management Standard file set. The app watches for estimate files in local folders.
+- DBF: dBASE file format used by decoded estimate data.
+- AD1/AD2: Estimate DBF files decoded by `electron/decoder/decoder.js`.
+- LIN: Estimate line DBF file.
+- VEH: Vehicle DBF file.
+- TTL: Totals DBF file.
+- PFH/PFL/PFM/STL: Additional estimate/system DBF files decoded when present.
+- Watch path: Local directory watched by chokidar.
+- File scan: Manual scan of configured watch paths.
+- Import: Decode local estimate files and upsert the resulting job/joblines into Hasura.
+
+## Rules and Programs
+
+- MPI: Manitoba Public Insurance, a ruleset/insurer context used heavily in targets and line rules.
+- SGI: Saskatchewan Government Insurance, another ruleset context. Some UI warns SGI eligibility rules may fall back to MPI rules.
+- RCC: A reporting/eligibility flag surfaced as `sgi_rcc`/RCC-related UI.
+- Ruleset: Date/rule bundle used by decoder logic to mark/interpret joblines.
+- V1/V2/V3 rulesets: Decoder-era rulesets selected by close date.
+- Claims Clerk: Domain rule engine that flags line-level issues/alerts.
+- Estimate Scrubber / ES: External API workflow that validates/scrubs estimate JSON and returns a report.
+- ES API key: Shop-specific API key stored on `bodyshops.es_api_key`.
+
+## Common Database Fields
+
+Jobs:
+
+- `id`: UUID primary key.
+- `bodyshopid`: Owning bodyshop.
+- `clm_no`: Claim number.
+- `ro_number`: Repair order number.
+- `ins_co_nm`: Insurer name.
+- `close_date`: Claim close date.
+- `loss_date`: Loss date.
+- `v_vin`: Vehicle VIN.
+- `v_makedesc` / `v_model`: Vehicle make/model.
+- `v_model_yr`: Vehicle model year.
+- `v_type`: Vehicle type.
+- `v_age`: Vehicle age.
+- `v_mileage`: Vehicle mileage.
+- `group`: Vehicle group.
+- `group_verified`: Whether group was manually verified.
+- `rates`, `totals`: JSON estimate rate/total blobs.
+- `requires_reimport`: Indicates data should be imported again.
+
+Joblines:
+
+- `id`: UUID primary key.
+- `jobid`: Parent job.
+- `line_no`: Estimate line number.
+- `unq_seq`: Source unique sequence id.
+- `line_ind`: Source line indicator.
+- `line_desc`: Line description.
+- `part_type`: Part type/category.
+- `db_price`: Database/reference price.
+- `act_price`: Actual price.
+- `price_diff`, `price_diff_pc`: Price difference fields.
+- `ignore`: Whether line is excluded from calculations.
+- `alerts`: Rules/claims-clerk alert payload.
+- `line_ref`: Parent/source line reference.
+
+Bodyshops:
+
+- `shopname`: Shop display name.
+- `accepted_ins_co`: JSON array of accepted insurers.
+- `targets`: JSON target config.
+- `groups`: JSON group config.
+- `features`: Feature config.
+- `channel`: Update/release channel.
+- `es_api_key`: Estimate scrubber key.
+- `ins_rule_set`: Shop ruleset, such as SGI.
+
+## UI/Code Abbreviations
+
+- `pct`, `pc`: Percent.
+- `ppd`: Price/part difference domain abbreviation used in settings/alerts.
+- `rps`: Repair performance score/system.
+- `asgn`: Assignment.
+- `insp`: Inspection.
+- `ded`: Deductible.
+- `supp`: Supplement.
+- `tlos`: Total loss indicator.
+- `prt`: Part.
+- `lbr`: Labor.
+- `amt`: Amount.
+- `qty`: Quantity.
+
diff --git a/.ai/electron-main.md b/.ai/electron-main.md
new file mode 100644
index 0000000..8caafd7
--- /dev/null
+++ b/.ai/electron-main.md
@@ -0,0 +1,152 @@
+# Electron Main, IPC, and Packaging Guide
+
+## Main Files
+
+- `electron/main.js`: Launch shim. Chooses bundled `dist-electron/main.cjs` in packaged mode when present, otherwise source.
+- `electron/main-src.js`: Source of truth for main process behavior.
+- `electron/preload.js`: Launch shim for preload.
+- `electron/preload-src.js`: Source preload bridge.
+- `scripts/build-electron.mjs`: Builds `dist-electron/main.cjs` and `dist-electron/preload.cjs`.
+
+## Main Process Responsibilities
+
+`electron/main-src.js` handles:
+
+- App/window lifecycle.
+- Application menu.
+- Sentry main process setup.
+- Auto-updater and update IPC.
+- DevTools configuration.
+- Third-party notice window.
+- Single-instance locking.
+- Tray behavior on minimize.
+- Initializing `electron-store`.
+- Loading IPC handlers.
+- Dynamic ESM imports for ESM-only Electron packages.
+
+## Store Initialization
+
+`electron-store` v11 is ESM-only. The app uses `electron/electron-store.js`:
+
+- `initializeStore()` dynamically imports and creates the store.
+- `store` is a proxy that throws if accessed before initialization.
+
+`main-src.js` must call:
+
+```js
+await initializeStore();
+initializeIpcHandlers();
+```
+
+before modules such as analytics, watcher, scanner, audit, or decoder read `store`.
+
+Store defaults include:
+
+- `deviceId`
+- `showChangeLog`
+- `enableNotifications`
+- `filePaths`
+- `accepted_ins_co`
+- `runWatcherOnStartup`
+- `polling`
+- `ins_rule_set`
+
+## ESM-Only Package Notes
+
+Current major upgrades made these ESM-only:
+
+- `electron-context-menu`
+- `electron-store`
+- `electron-is-dev`
+
+The app no longer uses `electron-is-dev`; it uses `!app.isPackaged` in main and `process.defaultApp`/`process.execPath` detection in preload.
+
+Use dynamic import for `electron-context-menu`:
+
+```js
+const { default: contextMenu } = await import("electron-context-menu");
+```
+
+## Sentry Electron
+
+Current dependency: `@sentry/electron@^7.13.0`.
+
+Main process import:
+
+```js
+const Sentry = require("@sentry/electron/main");
+```
+
+Renderer import:
+
+```js
+import * as Sentry from "@sentry/electron/renderer";
+```
+
+Main setup uses:
+
+```js
+ipcMode: Sentry.IPCMode.Protocol
+```
+
+Keep protocol mode unless deliberately changing Sentry IPC behavior. It avoids the deprecated Electron preload path Sentry can otherwise use.
+
+## DevTools
+
+Current behavior:
+
+- Dev mode: DevTools enabled and auto-open unless `ELECTRON_OPEN_DEVTOOLS=0`.
+- Packaged mode: DevTools disabled unless `ELECTRON_ENABLE_DEVTOOLS=1`.
+- Packaged auto-open: requires `ELECTRON_OPEN_DEVTOOLS=1`.
+- React DevTools extension installation: opt-in with `ELECTRON_INSTALL_REACT_DEVTOOLS=1`.
+
+Chrome DevTools can emit Electron backend console noise such as `Autofill.enable` and `Autofill.setAddresses` protocol errors. That noise is tied to DevTools/extension behavior, not app runtime failure.
+
+## IPC Modules
+
+Shared registration:
+
+- `electron/ipc-main-handler.js`
+
+Imported modules:
+
+- `electron/file-watcher/file-watcher-ipc.js`
+- `electron/file-scan/file-scan-ipc.js`
+- `electron/audit/audit-ipc.js`
+
+Avoid importing `mainWindow` from `main-src.js` in IPC modules. That caused circular dependency warnings. Use:
+
+```js
+const parentWindow = BrowserWindow.fromWebContents(event.sender);
+```
+
+for dialog parents, or `BrowserWindow.getAllWindows()[0]` for broadcast-style interactions when necessary.
+
+## Packaging
+
+`package.json` contains electron-builder config.
+
+Important scripts:
+
+- `npm run build:electron`: generates `dist-electron/`.
+- `npm run pack`: local unpacked package check with `--publish never` and `electron-builder.pack-check.cjs`.
+- `npm run dist`: full build/package using package config.
+- `npm run distp`: publishes. Use only when explicitly requested.
+- `npm run distnopublish`: full build/package with publishing disabled.
+
+`electron-builder.pack-check.cjs` disables Azure Trusted Signing config for pack checks:
+
+```js
+azureSignOptions: null
+```
+
+The pack check may still locally sign the unpacked executable with signtool. That is not publishing.
+
+Generated artifacts:
+
+- `dist-electron/`: bundled main/preload, ignored.
+- `build/`: renderer production build, ignored.
+- `dist/`: electron-builder output, ignored.
+
+Do not manually edit generated artifacts.
+
diff --git a/.ai/file-map.md b/.ai/file-map.md
new file mode 100644
index 0000000..f48ed4a
--- /dev/null
+++ b/.ai/file-map.md
@@ -0,0 +1,127 @@
+# File Map
+
+Use this as a quick locator before making changes.
+
+## Root
+
+- `package.json`: scripts, dependencies, electron-builder config, product metadata.
+- `package-lock.json`: npm dependency lock.
+- `vite.config.js`: Vite renderer config.
+- `index.html`: Vite app HTML entry.
+- `README.md`: old Create React App boilerplate; partially stale.
+- `Usage.md`: release usage notes; ignored by git but present.
+- `deployment.md`: deployment note; very terse.
+- `update-targets.md`: historical GraphQL target load example.
+- `SGI.md`: SGI-related domain notes.
+- `electron-builder.pack-check.cjs`: no-publish local packaging config for `npm run pack`.
+- `.gitignore`: generated artifacts and local secret files.
+
+## Electron
+
+- `electron/main.js`: chooses source or bundled main process.
+- `electron/main-src.js`: main process source of truth.
+- `electron/preload.js`: chooses source or bundled preload.
+- `electron/preload-src.js`: context bridge for IPC/logger.
+- `electron/ipc-main-handler.js`: shared IPC registration.
+- `electron/electron-store.js`: async ESM-compatible electron-store wrapper.
+- `electron/analytics.js`: Amplitude analytics IPC.
+- `electron/changelog.json`: versioned release notes.
+- `electron/licenses.txt`: third-party notice content shown in the app.
+- `electron/file-watcher/`: chokidar watcher and watcher IPC.
+- `electron/file-scan/`: manual scan/delete estimate file logic and IPC.
+- `electron/decoder/`: DBF estimate decoding and ruleset application.
+- `electron/claims-clerk/`: line-level alert rules.
+- `electron/audit/`: audit spreadsheet dialog/parsing IPC.
+- `electron/estimate-scrubber/`: external estimate scrubber API integration.
+- `electron/notification-wrapper/`: native notification helper.
+
+## Renderer Entrypoints
+
+- `src/index.jsx`: React root, Redux Provider, MemoryRouter, PersistGate, Sentry renderer.
+- `src/App/App.jsx`: Apollo provider, AntD theme/app provider, auth check, top-level IPC side effects.
+- `src/App/App.styles.scss`: app-level styles.
+- `src/index.css`: global CSS.
+
+## Renderer Components
+
+- `src/components/pages/routes/routes.page.jsx`: authenticated app shell and routes.
+- `src/components/pages/jobs/`: main jobs page.
+- `src/components/pages/reporting/`: reporting page.
+- `src/components/pages/audit/`: audit page.
+- `src/components/pages/scan/`: scan page.
+- `src/components/pages/settings/`: settings page.
+- `src/components/pages/admin/`: admin page.
+- `src/components/pages/sign-in/`: sign-in page.
+- `src/components/organisms/jobs-list-latest/`: latest jobs infinite list.
+- `src/components/organisms/jobs-list-search/`: search jobs infinite list.
+- `src/components/organisms/jobs-detail/`: selected job detail panel.
+- `src/components/organisms/watcher-manager/`: file watcher controls.
+- `src/components/organisms/shop-settings/`: shop settings workflows.
+- `src/components/organisms/update-manager/`: updater UI.
+- `src/components/organisms/notification-modal/`: notification UI.
+- `src/components/molecules/jobs-lines-table/`: jobline table.
+- `src/components/molecules/estimate-scruber-results/`: estimate scrubber results UI. Note the folder name contains `scruber`.
+- `src/components/molecules/estimate-scrubber-button/`: estimate scrubber action.
+- `src/components/molecules/reporting-dates/`: reporting date range picker.
+- `src/components/templates/error-boundary.template.jsx`: app error boundary.
+- `src/components/templates/ipc-upsert-job/`: IPC import/upsert template.
+
+## State
+
+- `src/redux/store.js`: store, saga middleware, logger, persist store.
+- `src/redux/root.reducer.js`: combines reducers.
+- `src/redux/root.saga.js`: combines sagas.
+- `src/redux/application/`: watcher/app/update/selection/scrubber state.
+- `src/redux/user/`: auth/bodyshop/targets/notifications/dark mode.
+- `src/redux/reporting/`: report/audit/scorecard state.
+- `src/redux/scan/`: scan state.
+
+## GraphQL and Auth
+
+- `src/graphql/GraphQLClient.js`: Apollo links, auth, retry, Sentry, cache policies.
+- `src/graphql/jobs.queries.js`: job queries/mutations.
+- `src/graphql/joblines.queries.js`: jobline mutations.
+- `src/graphql/bodyshop.queries.js`: shop and notifications.
+- `src/graphql/user.queries.js`: user upsert/auth lookup.
+- `src/graphql/reporting.queries.js`: reporting queries.
+- `src/graphql/notification.queries.js`: notification acceptance.
+- `src/graphql/veh_group.queries.js`: vehicle groups.
+- `src/firebase/firebase.utils.js`: Firebase auth/app setup.
+
+## IPC
+
+- `src/ipc.types.json`: canonical IPC channel map.
+- `src/ipc.types.js`: ESM wrapper.
+- `src/ipc.types.commonjs.js`: CommonJS wrapper.
+- `src/ipc/ipc-renderer-handler.js`: central renderer IPC listeners.
+- `src/ipc/ipc-estimate-utils.js`: estimate upsert and close-date GraphQL helpers.
+
+## Utilities and Assets
+
+- `src/util/antdFeedback.js`: context-safe AntD message/notification bridge.
+- `src/util/day.js`: day/date setup.
+- `src/util/CalculateJobRps.js`: RPS calculation utility.
+- `src/util/GetJobTarget.js`: target calculation utility.
+- `src/util/decimalPrecision.js`: numeric precision utility.
+- `src/util/sorters.js`: table/list sort helpers.
+- `src/assets/`: app logos/images.
+- `src/icons/`: app icons by platform/size.
+- `public/`: web app static files.
+
+## Hasura and Firebase
+
+- `hasura/config.yaml`: Hasura project config.
+- `hasura/config.yaml.prod`: production Hasura config.
+- `hasura/metadata/`: tracked Hasura metadata.
+- `hasura/migrations/default/`: active SQL migrations.
+- `hasura/migrations_backup/`: historical migration backup.
+- `firebase/functions/`: Firebase functions project.
+- `firebase/firebase.json`: Firebase config.
+
+## Generated/Ignored
+
+- `build/`: renderer production output.
+- `dist-electron/`: bundled Electron main/preload output.
+- `dist/`: electron-builder output.
+- `node_modules/`: dependencies.
+
diff --git a/.ai/frontend.md b/.ai/frontend.md
new file mode 100644
index 0000000..5f74ac5
--- /dev/null
+++ b/.ai/frontend.md
@@ -0,0 +1,95 @@
+# Frontend Guide
+
+## Stack
+
+- React 18
+- Vite 6
+- Ant Design 5
+- React Router DOM 6 with `MemoryRouter`
+- Redux 5, redux-saga, redux-persist, reselect
+- Apollo Client 3
+- SCSS modules/files by component where present
+
+## Component Layout
+
+Components are organized by a loose atomic design convention:
+
+- `src/components/atoms/`
+- `src/components/molecules/`
+- `src/components/organisms/`
+- `src/components/templates/`
+- `src/components/pages/`
+
+File naming usually includes the level:
+
+- `jobs-detail.organism.jsx`
+- `jobs-list-item.molecule.jsx`
+- `loading-spinner.atom.jsx`
+- `error-boundary.template.jsx`
+- `jobs.page.jsx`
+
+Preserve this style for new code.
+
+## AntD 5 Rules
+
+Use current AntD 5 APIs:
+
+- `Dropdown menu={{ items, onClick }}` instead of `overlay`.
+- `Collapse items={[...]}` instead of `Collapse.Panel` children.
+- `expandIconPosition="start"` or `"end"`, not `"left"` or `"right"`.
+- `DatePicker.RangePicker presets={...}` instead of `ranges`.
+- `Table rowKey="stableId"` or a function using a real stable field; do not rely on the deprecated index argument.
+- Prefer AntD `App` context-aware feedback APIs.
+
+Global feedback:
+
+- Use `src/util/antdFeedback.js`.
+- Import `antdMessage`/`antdNotification` instead of static `message`/`notification` from `antd` in files outside the AntD app context.
+- `src/App/App.jsx` configures these through `AntdFeedbackBridge`.
+
+## Theming
+
+`src/App/App.jsx` wraps the app with:
+
+- `ConfigProvider`
+- `theme.darkAlgorithm` or `theme.defaultAlgorithm` based on Redux `darkMode`
+- AntD locale `en_US`
+- AntD `App`
+
+Dark mode is stored in Redux `user.darkMode`.
+
+## Data Loading Notes
+
+Apollo defaults are `network-only` for `query` and `watchQuery`. Components should be resilient to loading states and should not assume cached data is available.
+
+Pagination:
+
+- Latest jobs and search jobs use offset/limit style pagination.
+- Apollo cache merge policies exist for `Query.jobs` and `Query.search_jobs`.
+- Guard `fetchMoreResult` and previous data as arrays before spreading; an earlier crash came from assuming `prev.search_jobs` was iterable.
+
+Job detail:
+
+- Selection is debounced briefly to prevent a stale left-panel flash.
+- Show stable loading/skeleton states during selection/query transitions.
+- Guard against stale Apollo data that does not match the currently selected job id.
+
+## Redux Notes
+
+Reducers are old-style switch reducers with action constants. Sagas are used for side effects. When adding logic:
+
+- Add action type constants.
+- Add action creators.
+- Update reducers immutably.
+- Add selectors with `reselect` where state is consumed.
+- Add sagas for async or cross-system side effects.
+
+## Common UI Pitfalls
+
+- Avoid static AntD feedback APIs.
+- Avoid adding in-component globals/listeners without cleanup.
+- Keep table/list row keys stable.
+- Keep list pagination state defensive around empty or missing arrays.
+- Do not introduce new routing assumptions based on browser history; this is a `MemoryRouter` Electron app.
+- Use existing visual density. This is an operational desktop app, not a marketing site.
+
diff --git a/.ai/project-overview.md b/.ai/project-overview.md
new file mode 100644
index 0000000..bd24901
--- /dev/null
+++ b/.ai/project-overview.md
@@ -0,0 +1,48 @@
+# Project Overview
+
+ImEX RPS is a desktop repair performance system for body shops. It imports estimating-system files, decodes estimates into jobs and joblines, stores and reads them through Hasura GraphQL, and gives users workflows for job review, reporting, audit, scan/import, settings, admin maintenance, updates, and estimate scrubbing.
+
+## Product Concepts
+
+- Bodyshop: The shop/account a signed-in user can access.
+- User association: A user is linked to one or more bodyshops through Hasura data.
+- Job: A repair estimate/claim. Jobs contain claim number, owner/customer fields, vehicle information, insurer, close/loss dates, totals, rates, group data, flags, and related joblines.
+- Jobline: A decoded estimate line. Joblines contain part/labor data, pricing deltas, ignore flags, ruleset-derived booleans, and alert metadata.
+- Targets/groupings: Config data used to calculate target percentages and vehicle group eligibility.
+- Notifications: Hasura-backed shop/user notifications shown in the app.
+- Watch paths: Local folders where Electron watches for estimate files.
+- Scan: Manual folder scan for estimate files.
+- Audit: Spreadsheet-driven workflow comparing claim data against cached jobs.
+- Estimate scrubber: External API workflow that sends estimate JSON and opens/sends scrub reports.
+
+## Main User Workflows
+
+- Sign in with Firebase auth.
+- Load user/bodyshop/notifications from Hasura after auth.
+- Configure watched folders and shop settings.
+- Watch or scan folders for estimate files.
+- Decode estimates in Electron main process.
+- Upsert jobs/joblines through renderer GraphQL helpers.
+- Review jobs and joblines in the Jobs page.
+- Search and paginate jobs.
+- Generate reporting and scorecards over date ranges.
+- Run audits from selected spreadsheets.
+- Send eligible estimates to the estimate scrubber service.
+- Receive update notices through electron-updater/S3 publishing.
+
+## External Systems
+
+- Hasura GraphQL/Postgres: Primary app data store.
+- Firebase: Authentication.
+- S3 updater bucket: Electron auto-update publishing target.
+- Sentry: Renderer and main-process error telemetry.
+- Amplitude: Main-process analytics through IPC.
+- Estimate scrubber API: External estimate validation/report flow.
+- Local file system: Estimate file watcher, scan, and DBF decoding.
+
+## Legacy Context
+
+The repository started from Create React App but now uses Vite. Some docs and comments are old. Prefer `package.json` scripts and current code over README boilerplate.
+
+The app uses a mixture of older class-era Redux patterns and current library versions. Preserve working conventions unless a task specifically asks for modernization.
+
diff --git a/.ai/recent-changes.md b/.ai/recent-changes.md
new file mode 100644
index 0000000..21c0d06
--- /dev/null
+++ b/.ai/recent-changes.md
@@ -0,0 +1,105 @@
+# Recent Changes and Migration Context
+
+This file captures recent cleanup/migration work so future agents do not reverse it.
+
+## AntD 5 Deprecation Cleanup
+
+Warnings addressed:
+
+- `Collapse expandIconPosition` left/right deprecated.
+- `rc-collapse children` deprecated.
+- `Table rowKey` index parameter deprecated.
+- Static `message` cannot consume dynamic theme context.
+- `Dropdown overlay` deprecated.
+- `RangePicker ranges` deprecated.
+
+Patterns now used:
+
+- `Collapse items`
+- `expandIconPosition="end"`
+- `Dropdown menu`
+- stable table row keys
+- `RangePicker presets`
+- `src/util/antdFeedback.js` for feedback APIs
+- AntD `` wrapper and bridge in `src/App/App.jsx`
+
+## Redux CreateStore Warning
+
+`src/redux/store.js` imports:
+
+```js
+import { legacy_createStore as createStore, applyMiddleware, compose } from "redux";
+```
+
+This intentionally keeps the current Redux architecture while avoiding the visual deprecation warning. Do not change to plain `createStore`.
+
+## Job Detail Flash Fix
+
+`src/components/organisms/jobs-detail/jobs-detail.organism.jsx` debounces selected job id and shows a skeleton during transitions. This prevents a fraction-of-a-second stale/partial render in the left panel.
+
+When editing this area:
+
+- Preserve stale-data guards.
+- Preserve a stable loading state when selected id changes.
+- Do not render details for a job whose id does not match current selection.
+
+## Apollo Pagination/Cache Fixes
+
+`src/graphql/GraphQLClient.js` includes offset merge policies:
+
+- `Query.jobs`
+- `Query.search_jobs`
+
+List components were hardened against missing previous/incoming arrays.
+
+## Electron Package Upgrades
+
+Packages upgraded together:
+
+- `electron-context-menu` to `^4.1.2`
+- `electron-is-dev` to `^3.0.1`
+- `electron-store` to `^11.0.2`
+- `electron` to `^42.3.0`
+- `electron-builder` to `^26.8.1`
+- `@sentry/electron` to `^7.13.0`
+
+Important migration consequences:
+
+- `electron-store` is initialized asynchronously via dynamic import.
+- `electron-context-menu` is dynamically imported.
+- `electron-is-dev` is no longer used in runtime code; use `app.isPackaged`/process checks.
+- Sentry uses protocol IPC mode.
+- Electron builder pack check uses `electron-builder.pack-check.cjs`.
+
+## Electron Warning Cleanup
+
+Circular dependency warning fixed by removing `mainWindow` export/import patterns. IPC modules use Electron APIs directly:
+
+```js
+BrowserWindow.fromWebContents(event.sender)
+```
+
+Sentry preload deprecation warnings were addressed by using protocol IPC mode:
+
+```js
+ipcMode: Sentry.IPCMode.Protocol
+```
+
+DevTools behavior:
+
+- Development opens DevTools by default again.
+- Use `ELECTRON_OPEN_DEVTOOLS=0` to suppress.
+- React DevTools extension install remains opt-in.
+
+## Pack Check Safety
+
+User specifically requested pack checks without publishing.
+
+`package.json`:
+
+```json
+"pack": "electron-builder --dir --publish never --config electron-builder.pack-check.cjs"
+```
+
+`electron-builder.pack-check.cjs` disables Azure signing options for this local check. Do not remove `--publish never` from the pack script.
+
diff --git a/.ai/workflows.md b/.ai/workflows.md
new file mode 100644
index 0000000..d874d45
--- /dev/null
+++ b/.ai/workflows.md
@@ -0,0 +1,141 @@
+# Development, Verification, and Release Workflows
+
+## Local Development
+
+```powershell
+npm install
+npm run dev
+```
+
+This runs:
+
+- Vite renderer dev server on `http://localhost:3006`
+- Electron app pointed at that dev server
+
+The app uses `MemoryRouter`, so browser URL routing behavior does not match a normal web app.
+
+## Build Verification
+
+Renderer build:
+
+```powershell
+npm run build
+```
+
+Electron main/preload bundle:
+
+```powershell
+npm run build:electron
+```
+
+Run both for most cross-process changes.
+
+Known existing build warnings:
+
+- A warning around `true || j.close_date` in `src/components/pages/admin/admin.page.jsx`.
+- Vite chunk-size warnings for large bundles.
+
+Do not treat those as newly introduced unless your change touches them.
+
+## Packaging Check
+
+Use:
+
+```powershell
+npm run pack
+```
+
+This runs:
+
+```text
+electron-builder --dir --publish never --config electron-builder.pack-check.cjs
+```
+
+It is the preferred "does it package?" check because it avoids publishing.
+
+## Publishing
+
+Publishing is configured through electron-builder S3 settings in `package.json`. The updater checks periodically.
+
+Do not run publishing scripts unless explicitly requested:
+
+- `npm run distp`
+- Any direct `electron-builder --publish always`
+
+If asked to release:
+
+1. Confirm the version in `package.json`.
+2. Run `npm run build`.
+3. Run `npm run build:electron`.
+4. Run a no-publish package check first.
+5. Only then run the requested publish command.
+
+## Auto Updates
+
+Main process:
+
+- Uses `electron-updater`.
+- `autoUpdater.autoDownload = true`.
+- Checks every 30 minutes after app ready.
+- Sends update events/progress to renderer through IPC.
+- Renderer `UpdateManagerOrganism` handles UI.
+
+Release notes:
+
+- Stored in `electron/changelog.json`.
+- Main process reads `require("./changelog.json")[app.getVersion()]`.
+- Store key `showChangeLog` controls initial display.
+
+## Hasura
+
+Hasura config and migrations live under `hasura/`.
+
+Be careful with migrations:
+
+- Current migrations are under `hasura/migrations/default/`.
+- `hasura/migrations_backup/` is historical backup material.
+- Metadata under `hasura/metadata/` should match Hasura's generated layout.
+
+When changing GraphQL queries, verify the Hasura metadata/schema supports selected fields.
+
+## Sentry Source Maps
+
+Script:
+
+```powershell
+npm run sentry:sourcemaps
+```
+
+Requires a valid `.sentryclirc`/token and should only be run when intentionally uploading source maps.
+
+## Troubleshooting
+
+Electron backend console DevTools noise:
+
+- `Autofill.enable` and `Autofill.setAddresses` errors are Chromium DevTools protocol noise.
+- They can appear when Chrome DevTools or React DevTools are open.
+
+Electron circular dependency warning:
+
+- Do not import `mainWindow` from `main-src.js` in other Electron modules.
+- Use `BrowserWindow.fromWebContents(event.sender)` for dialogs.
+
+AntD theme/static feedback warning:
+
+- Use `antdMessage`/`antdNotification` from `src/util/antdFeedback.js`.
+- Ensure `AntdFeedbackBridge` is mounted inside AntD ``.
+
+Apollo cache replacement warning:
+
+- Confirm field policies in `GraphQLClient.js`.
+- Add/adjust merge policies for newly paginated fields.
+
+Search pagination crash:
+
+- Guard `prev?.search_jobs` and `fetchMoreResult?.search_jobs` before spreading.
+
+Git ignore of generated files:
+
+- `.gitignore` includes `/dist-electron/`.
+- If generated files still show in status, they are probably already tracked; remove from index with `git rm --cached -r dist-electron` after confirming the local files can stay.
+
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..f06750c
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,15 @@
+# Copilot Instructions for ImEX RPS
+
+Read `AGENTS.md` first. It contains the current project architecture, safety rules, workflows, and migration context.
+
+When proposing or generating code:
+
+- Use npm scripts and current Vite/Electron workflows, not stale Create React App/yarn instructions.
+- Keep changes narrow and preserve existing style.
+- Do not edit generated `build/`, `dist/`, or `dist-electron/`.
+- Do not suggest publish commands unless the user explicitly asks to publish.
+- Prefer AntD v5 APIs and avoid deprecated props.
+- Preserve Electron security defaults: `contextIsolation: true`, `nodeIntegration: false`, preload bridge for renderer IPC.
+- Avoid circular Electron main-process imports; IPC modules should not import `mainWindow` from `main-src.js`.
+- Use `.ai/` files for deeper domain and architecture context.
+
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..799ce53
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,162 @@
+# ImEX RPS Agent Guide
+
+This file is the first stop for coding agents working in this repository. It is intentionally practical: read this before changing code, then use the deeper files in `.ai/` when you need more context.
+
+## Project Snapshot
+
+ImEX RPS is an Electron desktop app with a Vite/React renderer. It is used by body shops to import, inspect, report on, and audit repair estimate data. The app reads estimate files from configured local folders, decodes DBF-based estimate data in the Electron main process, stores jobs/joblines in Hasura/Postgres through GraphQL, and presents workflows for jobs, reporting, scanning, settings, admin work, audits, and estimate scrubbing.
+
+Primary technologies:
+
+- Electron 42, electron-builder 26, Vite 6, React 18
+- Ant Design 5
+- Redux 5, redux-saga, redux-persist, reselect
+- Apollo Client 3 against a Hasura GraphQL endpoint
+- Firebase authentication
+- Sentry Electron 7
+- Hasura metadata and SQL migrations under `hasura/`
+
+## Fast Start
+
+Use npm scripts, not the stale yarn commands in `README.md`.
+
+```powershell
+npm install
+npm run dev
+```
+
+Useful scripts:
+
+- `npm run start` starts Vite on `http://localhost:3006`.
+- `npm run electron` starts Electron.
+- `npm run dev` runs Vite and Electron together with `concurrently`.
+- `npm run build` builds the renderer to `build/`.
+- `npm run build:electron` bundles `electron/main-src.js` and `electron/preload-src.js` into `dist-electron/`.
+- `npm run pack` performs a local unpacked electron-builder package check with `--publish never`.
+- `npm run distp` publishes. Do not run it unless the user explicitly asks to publish.
+- `npm run distnopublish` builds a distributable with publish disabled.
+
+Expected local runtime:
+
+- Node must satisfy Electron 42 requirements. At the time of the upgrade, Node 22.22.1 was used successfully.
+- `VITE_APP_GRAPHQL_ENDPOINT` must be available in the renderer environment.
+- Firebase config lives in `src/firebase/firebase.utils.js`.
+- Electron dev mode loads `http://localhost:3006`; packaged mode loads `build/index.html`.
+
+## Important Safety Rules
+
+- Do not publish releases unless the user explicitly says to publish.
+- `npm run pack` is safe for local packaging checks because it includes `--publish never` and uses `electron-builder.pack-check.cjs`.
+- `dist-electron/`, `build/`, and `dist/` are generated artifacts and are ignored. Do not manually edit them.
+- Do not commit local secrets. The repo contains legacy-sensitive assets such as `certificate.p12`, deployment notes, and Sentry/Firebase/AWS-related configuration. Treat them carefully.
+- Avoid broad refactors. This project has older patterns and domain-heavy workflows; make narrow changes and preserve behavior.
+- Be careful with Electron main/renderer boundaries. Renderer code should use the exposed preload bridge on `window.ipcRenderer`; main-process code should register IPC handlers under `electron/`.
+
+## Architecture Map
+
+Renderer entry:
+
+- `src/index.jsx` wires Redux, redux-persist, `MemoryRouter`, Sentry renderer, and ``.
+- `src/App/App.jsx` wires Apollo, AntD `ConfigProvider`, AntD `App`, auth session check, IPC setup, and authorized/unauthorized routing.
+- `src/components/pages/routes/routes.page.jsx` defines app pages: jobs, reporting, audit, scan, settings, admin.
+
+Electron entry:
+
+- `electron/main.js` chooses source vs bundled Electron main file.
+- `electron/main-src.js` is the source of truth for main-process window creation, Sentry main, auto-updater, app menu, DevTools behavior, and global IPC initialization.
+- `electron/preload-src.js` exposes `window.ipcRenderer` and `window.logger`.
+- `electron/ipc-main-handler.js` registers shared IPC channels and imports file watcher, file scan, audit, decoder, and estimate scrubber handlers.
+- `scripts/build-electron.mjs` produces `dist-electron/main.cjs` and `dist-electron/preload.cjs`.
+
+State/data:
+
+- `src/redux/store.js` still uses Redux core with `legacy_createStore` to avoid Redux's visual createStore deprecation.
+- Root reducers: `application`, `user`, `reporting`, `scan`.
+- Sagas coordinate auth, user/shop setup, reporting, scanning, and application actions.
+- `src/graphql/GraphQLClient.js` sets Apollo auth, retry, Sentry, logger, error links, and cache field policies for `jobs` and `search_jobs`.
+- GraphQL operations live in `src/graphql/*.queries.js`.
+
+Domain logic:
+
+- `electron/decoder/decoder.js` decodes estimate files and applies MPI/SGI/ruleset logic.
+- `electron/file-watcher/` watches configured estimate folders.
+- `electron/file-scan/` scans configured folders for estimates.
+- `electron/audit/` reads audit spreadsheets.
+- `electron/estimate-scrubber/` sends estimate JSON to the external scrubber API and opens/sends report results.
+- `electron/claims-clerk/` computes jobline alerts.
+
+## Current Conventions
+
+Frontend:
+
+- Components are organized by atomic-ish folders: `atoms`, `molecules`, `organisms`, `templates`, `pages`.
+- File names generally follow `name.type.jsx` and optional `name.type.styles.scss`.
+- Use Ant Design 5 APIs. Avoid deprecated props such as `Dropdown overlay`, `Collapse.Panel` children, `expandIconPosition="left/right"`, `RangePicker ranges`, and `Table rowKey` functions that rely on index.
+- Use `src/util/antdFeedback.js` for message/notification calls outside React component context. Static AntD `message`/`notification` calls can miss dynamic theme context.
+- Keep UI state stable during data transitions. Job detail selection uses a short debounce/skeleton to avoid flashing stale detail content.
+
+Electron:
+
+- `electron-store` v11 is ESM-only. Use `initializeStore()` before modules that read `store`, then access `store` through the proxy exported from `electron/electron-store.js`.
+- `electron-context-menu` v4 is ESM-only. Import dynamically in `app.whenReady()`.
+- Do not reintroduce circular imports from `electron/main-src.js` into IPC modules. IPC modules should use `BrowserWindow.fromWebContents(event.sender)` or `BrowserWindow.getAllWindows()` where needed.
+- Sentry main uses `ipcMode: Sentry.IPCMode.Protocol`; keep this unless deliberately changing Sentry IPC behavior.
+- DevTools are enabled in dev and auto-open by default. Set `ELECTRON_OPEN_DEVTOOLS=0` to suppress auto-open. In packaged builds DevTools are opt-in via `ELECTRON_ENABLE_DEVTOOLS=1` and auto-open via `ELECTRON_OPEN_DEVTOOLS=1`.
+- React DevTools extension install is opt-in with `ELECTRON_INSTALL_REACT_DEVTOOLS=1`. It can trigger Chromium DevTools protocol noise.
+
+GraphQL/Apollo:
+
+- Default Apollo query/watchQuery fetch policy is `network-only`; do not assume Apollo cache is the source of truth.
+- Apollo cache has custom offset merge functions for `Query.jobs` and `Query.search_jobs` to avoid cache replacement warnings during pagination.
+- Firebase current user token is attached as `Authorization: Bearer ` through `authLink`.
+
+## Recent Maintenance Context
+
+Recent warning/deprecation cleanup included:
+
+- AntD v5 deprecations fixed for Collapse, Dropdown, RangePicker, Table rowKey, and static message/notification usage.
+- Redux `createStore` deprecation warning avoided with `legacy_createStore`.
+- Apollo cache warning fixed with field policies for `jobs` and `search_jobs`.
+- Job detail left-panel flash reduced by debouncing selected job id and using a skeleton.
+- Electron circular dependency warnings removed by avoiding `mainWindow` export/import.
+- Electron Sentry preload deprecation path avoided with protocol IPC mode.
+- Electron package upgrades completed for `electron`, `electron-builder`, `electron-context-menu`, `electron-is-dev`, `electron-store`, and `@sentry/electron`.
+- `dist-electron/` is ignored and should remain generated only.
+
+## Verification Expectations
+
+For most renderer/main changes:
+
+```powershell
+npm run build
+npm run build:electron
+```
+
+For Electron package or builder changes:
+
+```powershell
+npm run pack
+```
+
+Remember: `npm run pack` is configured to avoid publishing. It may still perform local signing of the unpacked executable.
+
+For AntD deprecation checks, if `antd-style` tooling is available:
+
+```powershell
+npx antd-style-cli lint src --only deprecated
+```
+
+If a command is unavailable, report that clearly and run the nearest reliable build/check instead.
+
+## More Context
+
+- `.ai/project-overview.md`: product/domain summary.
+- `.ai/architecture.md`: process, renderer, state, and data architecture.
+- `.ai/electron-main.md`: Electron-specific lifecycle, packaging, IPC, and upgrade notes.
+- `.ai/frontend.md`: React/AntD/Redux conventions and common UI pitfalls.
+- `.ai/data-graphql-hasura.md`: GraphQL, Hasura, auth, cache, and schema notes.
+- `.ai/workflows.md`: development, packaging, release, and troubleshooting workflows.
+- `.ai/recent-changes.md`: migration and warning cleanup history.
+- `.ai/file-map.md`: important files and directories by responsibility.
+- `.ai/domain-glossary.md`: project/domain terms used across code and UI.
+- `.github/copilot-instructions.md`, `CLAUDE.md`, and `GEMINI.md` all point agents back to this guide.
diff --git a/AI_CONTEXT.md b/AI_CONTEXT.md
new file mode 100644
index 0000000..6418e8f
--- /dev/null
+++ b/AI_CONTEXT.md
@@ -0,0 +1,26 @@
+# AI Context Index
+
+This is the root index for AI/code-agent context in ImEX RPS. Start with `AGENTS.md`; use the `.ai/` files for deeper context.
+
+## Read Order
+
+1. `AGENTS.md`
+2. `.ai/project-overview.md`
+3. `.ai/architecture.md`
+4. `.ai/workflows.md`
+5. Task-specific files:
+ - `.ai/frontend.md` for React, AntD, Redux, and UI work.
+ - `.ai/electron-main.md` for Electron main/preload/IPC/packaging work.
+ - `.ai/data-graphql-hasura.md` for GraphQL, Apollo, Hasura, Firebase auth, schema, and migrations.
+ - `.ai/recent-changes.md` for current deprecation cleanup and package migration context.
+ - `.ai/file-map.md` for locating important code quickly.
+ - `.ai/domain-glossary.md` for domain terms and abbreviations.
+
+## High-Signal Rules
+
+- Use npm scripts. The old README still mentions yarn/Create React App.
+- Do not publish unless explicitly asked. `npm run pack` is the safe local packaging check.
+- Do not edit generated `build/`, `dist/`, or `dist-electron/`.
+- Keep Electron main/renderer separation clean.
+- Use AntD v5 APIs and `src/util/antdFeedback.js` for global message/notification calls.
+- Treat local certs, deployment scripts, Sentry DSNs, Firebase config, and AWS notes as sensitive.
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..d699c10
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,17 @@
+# Claude Instructions
+
+Start with `AGENTS.md`. It is the canonical guide for this repository.
+
+Additional context lives in `.ai/`:
+
+- `.ai/project-overview.md`
+- `.ai/architecture.md`
+- `.ai/frontend.md`
+- `.ai/electron-main.md`
+- `.ai/data-graphql-hasura.md`
+- `.ai/workflows.md`
+- `.ai/recent-changes.md`
+- `.ai/file-map.md`
+- `.ai/domain-glossary.md`
+
+Do not publish releases unless the user explicitly asks. Use `npm run pack` for local packaging checks.
diff --git a/GEMINI.md b/GEMINI.md
new file mode 100644
index 0000000..daf7007
--- /dev/null
+++ b/GEMINI.md
@@ -0,0 +1,17 @@
+# Gemini Instructions
+
+Start with `AGENTS.md`. It is the canonical guide for this repository.
+
+Additional context lives in `.ai/`:
+
+- `.ai/project-overview.md`
+- `.ai/architecture.md`
+- `.ai/frontend.md`
+- `.ai/electron-main.md`
+- `.ai/data-graphql-hasura.md`
+- `.ai/workflows.md`
+- `.ai/recent-changes.md`
+- `.ai/file-map.md`
+- `.ai/domain-glossary.md`
+
+Do not publish releases unless the user explicitly asks. Use `npm run pack` for local packaging checks.
diff --git a/electron/main-src.js b/electron/main-src.js
index 06adaa0..edcb88d 100644
--- a/electron/main-src.js
+++ b/electron/main-src.js
@@ -8,7 +8,8 @@ const Sentry = require("@sentry/electron/main");
const isDev = !app.isPackaged;
const enableDevTools = isDev || process.env.ELECTRON_ENABLE_DEVTOOLS === "1";
-const openDevToolsOnStart = enableDevTools && process.env.ELECTRON_OPEN_DEVTOOLS === "1";
+const openDevToolsOnStart =
+ enableDevTools && (isDev ? process.env.ELECTRON_OPEN_DEVTOOLS !== "0" : process.env.ELECTRON_OPEN_DEVTOOLS === "1");
const installReactDevTools = process.env.ELECTRON_INSTALL_REACT_DEVTOOLS === "1";
//const Nucleus = require("nucleus-nodejs");
@@ -209,8 +210,8 @@ function createWindow() {
app.quit();
});
- // Open DevTools only when explicitly requested. DevTools itself emits
- // Chromium protocol noise such as Autofill.* messages in Electron.
+ // Auto-open DevTools in dev. DevTools itself can emit Chromium protocol
+ // noise such as Autofill.* messages in Electron.
if (openDevToolsOnStart) {
mainWindow.webContents.openDevTools({
// mode: "detach"