# Failure diagnostics — Functional Specification

**Status:** Approved v1.2 · 2026-07-21

**Scope of this document:** User-visible collection, inspection, and copying of safe diagnostics for store checks. Technical design and implementation follow after this specification is approved.

---

## 1. Purpose

When a store check fails, the current generic failure label is not enough to distinguish a timeout, store response, parsing problem, host-browser problem, or temporary network failure. The app must let the user inspect and copy a useful diagnostic report so a failure reproduced on Android or Windows can be investigated without connecting development tools.

This feature is for support and troubleshooting. It does not turn the app into a general Android `logcat`, Windows event-log, or network-inspection tool.

## 2. Entry points and status behavior

- Diagnostics are opened from the `Diagnostics` section of the Settings surface. The main comparison UI has no global diagnostics link and no per-store diagnostic information icons.
- Successful and empty results do not show a warning, but their attempts remain available as context in the current diagnostic session.
- Re-fetching a store appends a new attempt; it does not erase the preceding failed attempt.
- Retry and human-check actions remain on the affected store status; the diagnostic report does not duplicate them.
- A later successful re-fetch does not erase the earlier failure, so the evidence remains retrievable from Settings after recovery.

Final wording for all supported languages remains centralized with the other UI strings.

## 3. Diagnostic session

The app keeps a bounded, in-memory diagnostic session containing the latest **50 store-check attempts**. Oldest attempts are discarded first.

Each attempt records only structured support data:

- attempt time;
- store ID and display name;
- canonical part-number query;
- host kind (`Android`, `Windows desktop`, other desktop, or web);
- app version when available;
- outcome: success, empty, check required, timeout, paused, HTTP failure, transport failure, parsing/validation anomaly, or unknown failure;
- existing machine-readable error code;
- HTTP status when one exists;
- total duration;
- whether the result came from cache;
- number of valid offers returned;
- a short sanitized error message when the lower layer supplied one;
- safe host-browser lifecycle events relevant to that attempt's store, when available.

The session survives view changes and per-store re-fetches, but **v1 does not persist diagnostics across an app restart**. A later version may add opt-in persistence if session reports prove insufficient.

## 4. Global diagnostic report

Opening `Debug report` from Settings shows recent attempts across all stores, newest first. It does not require a selected store or failure.

Each detailed attempt uses readable labels and includes:

- store and query;
- time and duration;
- outcome and error code;
- HTTP status, cache state, and offer count;
- sanitized error detail;
- a short chronological browser/transport trail when the host can provide one.

Unknown or unavailable values are shown as `Not available`; they are not invented. When the session contains no attempts, the report view shows a localized empty explanation. Raw exception stacks are not shown in the primary summary, but safe application-owned stack locations may be included in the copied report during development builds.

## 5. Copying a report

The panel provides `Copy diagnostic report`. It copies a plain-text report suitable for pasting into an issue, email, or chat.

The report contains:

1. report timestamp and app/host information;
2. recent cross-store attempt summaries, newest first;
3. detailed safe host-browser lifecycle trails for the recorded attempts, when present.

Copy success or failure is visibly confirmed. If clipboard access is unavailable, the report remains selectable in the panel so the user can copy it manually. Native file export/share is out of scope for v1; plain-text copy is the meaning of `pull logs` in this version.

## 6. Safe logging rules

Diagnostic collection must never include:

- cookies or cookie values;
- request or response headers;
- Cloudflare/Turnstile tokens or challenge payloads;
- raw HTML, JSON response bodies, or page text;
- local-storage or purchase-plan contents;
- full external product/search URLs;
- device identifiers, IP addresses, account data, or unrelated Android/Windows logs.

Allowed URL-derived data is limited to the already-visible store ID and canonical part-number query. Error text is length-limited and sanitized before it enters the diagnostic session. Native browser events use an allow-list of event names and scalar fields rather than arbitrary log strings.

## 7. Platform consistency

- **Android:** include safe events from the per-store native WebView lifecycle, such as navigation started/finished, main-frame status, challenge detected/cleared, selector found/missing, timeout, and final result. Do not expose general `logcat`.
- **Windows/desktop:** include the equivalent resident Chromium lifecycle events where available.
- **Web/server mode:** include the shared engine response and HTTP transport outcome; native browser events are marked unavailable.
- The report UI and copied report format are otherwise the same on every host.

## 8. Acceptance criteria

1. Settings exposes a global debug report without requiring a selected store.
2. A failed or check-required store exposes its ordinary retry or solve action but no diagnostic info icon.
3. Re-fetching after failure preserves the earlier attempt in the current diagnostic session.
4. The user can copy a readable report without Android Studio, `adb`, a terminal, or Windows developer tools.
5. The report distinguishes timeout, challenge required, paused circuit, HTTP status failure, and generic transport failure.
6. An Autodoc Android failure report includes its safe WebView challenge/navigation timeline.
7. Reports never contain cookies, headers, response bodies, raw page text, challenge tokens, or full external URLs.
8. The diagnostic buffer is bounded to 50 attempts and is cleared on app restart in v1.
9. Clipboard denial does not lose the report; selectable text remains visible.
10. Existing search, solve, and per-store re-fetch behavior remains unchanged, and removing contextual icons does not remove retained session evidence.

## 9. Out of scope for v1

- uploading reports automatically;
- remote telemetry or analytics;
- sending reports to a developer without an explicit user copy/share action;
- full Android `logcat`, Windows event logs, Chromium DevTools logs, or packet captures;
- raw store responses or screenshots;
- persistent logs across app restarts;
- native file attachment/export or operating-system share sheets.
