Skip to content

Latest commit

 

History

History
102 lines (87 loc) · 6.42 KB

AGENTS.md

File metadata and controls

102 lines (87 loc) · 6.42 KB

AGENTS.md — EVChargePilot

Read-only energy dashboard and local trip analyser for the SAIC MG4. The workspace AGENTS.md and normative workspace DESIGN.md apply; this file adds only ChargePilot's product boundary and commands.

Commit author: malys.training@gmail.com.

License exception: EVChargePilot's own sources use PolyForm Noncommercial 1.0.0, not the workspace MIT default. EVHardware remains separately licensed.

Product boundary

  • EVChargePilot reads vehicle state and writes its bounded trip/export files in app-private storage. A diagnostic report may additionally be written only after an explicit parked-user choice to a removable USB volume; it is bounded, atomic and never targets internal AAOS storage as a fallback.
  • It never changes a vehicle setting, controls charging, exposes a remote command surface, draws an overlay, or silently opens another application.
  • Vehicle property ids, service descriptors, transaction codes and firmware routing belong in standalone EVHardware. This app consumes typed EVHardware APIs only.
  • Missing telemetry remains null through acquisition, calculation and presentation. The UI renders an em dash and explains the unavailable source; it never substitutes zero.
  • Measured, derived and estimated values must be visibly named. A model may not be labelled as a vehicle measurement.

Driver UX

  • The live dashboard is passive while moving. Trip start/stop controls are enabled only when a readable speed is at or below 0.1 km/h.
  • No driver-facing overlay is permitted.
  • Preserve the asymmetric instrument + rail layout: SOC is the single display-sized value; secondary measurements must not compete with it.
  • Follow the workspace DESIGN.md exactly. Resources synchronized from tools/tokens/ are generated copies and must not be edited locally.

Shared energy calculations

  • EnergyTelemetryReader, snapshots, trip integration and persistence are owned by EVHardware and must remain JVM-tested there; do not fork them into this app.
  • Integrate only adjacent samples no more than five seconds apart. A larger gap represents unknown motion/energy and must not be filled by extrapolation.
  • Energy and consumption remain null until at least one valid power interval exists.
  • Climate telemetry is passive state, not energy consumption. Keep every climate field nullable, evidence-gate battery temperature per firmware, and never derive HVAC power from an on/off state or fan setting.
  • The app owns only sampling cadence, lifecycle and presentation.

Security

  • The stable manifest has no overlay, install or boot capability. INTERNET and ACCESS_FINE/COARSE_LOCATION are declared for route planning only, under CP-043 (analysis/CP-043_network_and_location.md): one HTTP entry point (RoutingTransport), https plus a single-host allowlist on the initial URL and every redirect hop, the key in a header and never a query string, no key in the APK, and no telemetry, trip or identifier on the wire. Any second socket or any widening of that payload is a security review, not a patch.
  • USB diagnostic export adds no storage permission: offer every mounted volume the app can already list except primary emulated storage, and fall back only to this app's directory on the same volume. Never require positive proof that a volume is removable — this head unit cannot give it, and demanding it is why exports found nothing.
  • The unstable channel checks GitHub's rolling unstable pre-release only after the driver double-taps the version on the Energy dashboard, then downloads a newer APK (app/src/unstable/.../update/). It is the second HTTP entry point and stays inside the same rules: https plus an exact-match host allowlist on the initial URL and every redirect hop, a size ceiling on the declared and the transferred length, and the archive only reaches shared storage after its signing certificate is proven identical to the running app's. It installs nothing — no REQUEST_INSTALL_PACKAGES, no pm install, no system UID — and the verified APK is written to the head unit's Download folder. That write is the one reason this app declares WRITE_EXTERNAL_STORAGE, in the unstable manifest only, capped at maxSdkVersion=28 and requested at runtime from the dashboard; a refusal falls back to this app's own Download directory on the same volume, the same shape the USB export uses, and the dialog names whichever path was used. Stable declares neither the permission nor any of that code. The USB diagnostic export still adds no storage permission and must not start.
  • Any new permission requires an allowlist change and a security review in the same commit.
  • Signing configuration comes only from environment variables or local Gradle properties.

Build and test

Run mise run test, mise run lint, or mise run build. mise run emulator-setup creates the complementary emulator-car (Automotive API 33) and emulator-screen (API 28, 1920×1080 panel with a 1920×720 app viewport) profiles; mise run run installs and launches the debug APK. JDK 17 and Android SDK 36 are used for compilation; the deployed minimum remains API 28. Emulator checks do not replace a vehicle pass on each supported firmware generation.

Continuation handoff

  • The implemented baseline is the passive dashboard, nullable shared energy snapshot, automatic foreground trip detection/recording with parked-only manual controls, bounded atomic trip history, crash diagnostics, stable/unstable variants, CI gates and the two emulator profiles documented in README.md.
  • Arrival-SOC prediction, charger routing and energy attribution are not implemented. Treat each as a separately scoped milestone with explicit evidence for every input; do not fill missing vehicle signals with inferred measurements.
  • Start app work by checking git status and the EVHardware submodule branch. Any shared telemetry model, property, unit, fallback or integration change starts in the standalone ../EVHardware repository, is tested and pushed there, then reaches this app through a submodule pointer update. Never develop library changes inside the nested checkout.
  • Before handing off a change, run mise run check and mise run build. For UI/lifecycle work, also run the API 28 screen emulator on its 1920×1080 panel with the target 1920×720 app viewport; for vehicle interfaces, record the remaining on-vehicle validation requirement rather than claiming emulator coverage.