# Workflow Spec — Guard‑driven state + `BaseException` (LLM‑only)

> Machine‑consumable, compact, deterministic. Scope: integrate `bug_handler` with state management so every failure is a `BaseException`, state stores the exception object (not a string), and reporting is handled by guards.

---

## 0. Symbols (exact names)

* Types: `BaseException`, `ApiException`, `UnexpectedException`, `ParsingException`, `PlatformOperationException`, `Severity`, `ReportEvent`.
* Guards: `guard<T>`, `guardSync<T>`, `parser<T>`, `normalizeError(...)`.
* Client: `BugReportClient.instance.createEvent(...)`, `BugReportClient.instance.report(...)`, `BugReportClient.instance.capture(...)`.
* HTTP helpers: `HttpStatusCodeInfo`.
* Policy (implicit via config): `Policy.minSeverity`, `Policy.reportHandled`, `Policy.environments`, `Policy.sampling`, `RateLimit`, `DedupeStrategy`.

---

## 1. Invariants (must)

* All thrown application errors are `BaseException` or subclasses.
* Repository/service boundaries convert foreign errors to `BaseException` before exiting the layer.
* State objects store `error: BaseException` (no string), and UI reads `error.userMessage`.
* Controllers/state‑managers invoke async work via `guard(...)` (or sync via `guardSync(...)`).
* If an incoming error is not a `BaseException`, it is normalized to one (`normalizeError` path) before reaching state.
* Guards initiate reporting via `BugReportClient` and respect configured `Policy`; delivery may be dropped by policy but state still receives the exception.
* Use stable `source` labels in guards for dedupe/grouping (format: `Feature.Module.Action`).

---

## 2. State model (generic; library‑agnostic)

* Keys (stable):

  * `status`: one of `idle | loading | ready | error`.
  * `data`: type `T | null`.
  * `error`: type `BaseException | null`.
* Transition rules:

  * `idle → loading` on request start.
  * Success: `loading → ready` and set `data`.
  * Failure: `loading → error` and set `error` (the `BaseException` returned by guard).

---

## 3. Layer responsibilities

* **Repository/Service**

  * Wrap I/O, platform, and parsing boundaries.
  * On failure: throw a specific `BaseException` subclass.
  * Never return raw SDK/library exceptions across the boundary.

* **Controller / Bloc / Notifier**

  * Call work via `guard(...)` with `source`.
  * On `Ok`: emit `ready`.
  * On `Err`: emit `error` with the returned `BaseException`.

* **UI**

  * Render `error.userMessage`.
  * Dev surfaces may display `error.devMessage` and/or `error.metadata`.

---

## 4. Exception taxonomy (use; do not invent new shapes unless required)

* HTTP: prefer `ApiException` (or an app subclass) with `HttpStatusCodeInfo(statusCode)`; include endpoint/method and response snippets in `metadata`.
* Auth/session: `AuthException` / `TokenException`.
* Data/model: `DataProcessingException` / `ParsingException`.
* Permissions: `PermissionException`.
* Platform channel/OS: `PlatformOperationException` (or `.fromPlatformException(...)`).
* Storage/cache: `StorageException` / `CacheException` / `SecureStorageException`.
* Validation (user input): `ValidationException` (usually non‑reportable).
* Fallback: `UnexpectedException` with `cause` and `stack`.

---

## 5. HTTP mapping policy (deterministic)

* On non‑2xx response: throw an `ApiException` (or app subclass) built from `HttpStatusCodeInfo(statusCode)`.
* Derive severity from `HttpStatusCodeInfo.errorSeverity` (5xx=`error`, 401/403=`warning`, 404=`info`, 429=`warning`).
* Set `userMessage` to a safe, human string; `devMessage` should include status/method/endpoint.
* Preserve request/response fragments under `metadata.http{...}` (avoid PII; sanitizers will further mask).

---

## 6. Guard semantics (from code)

* `guard<T>(action, {source, onSuccess, onError, manual, additionalContext})`:

  * try/catch → `normalizeError` to `BaseException` if needed.
  * Build `ReportEvent` via `BugReportClient.instance.createEvent(...)` (includes `manual` and `additionalContext`).
  * Send via `BugReportClient.instance.report(...)` (policy may drop; function still returns `Err`).
  * Returns `Ok<T>` or `Err<BaseException>`.
* `guardSync<T>`: same normalization; reporting is fire‑and‑forget.
* `parser<T>(build, data: raw)`: converts format/type errors to `ParsingException`.

---

## 7. Controller update contract (library‑agnostic)

* Input: result from `guard(...)`.
* On `Ok(value)`: set `status=ready`, `data=value`, `error=null`.
* On `Err(e)`: set `status=error`, `error=e`, `data` unchanged or `null` (project decision; be consistent).

---

## 8. Reporting contract

* Automatic: guards create and attempt to deliver a sanitized `ReportEvent` using current `ClientConfig` (transforms + sanitizers + policy).
* Manual: optionally call `BugReportClient.instance.capture(e, manual: true)` to include manual‑only context providers (e.g., UI/user).
* Note: policy gates (`minSeverity`, `reportHandled`, `environments`, `sampling`, rate‑limit, dedupe) may prevent delivery; state logic must not depend on delivery outcome.

---

## 9. Normalization fallback rules (exact)

* If error is `BaseException`: passthrough.
* If error is `PlatformException`: map with `PlatformOperationException.fromPlatformException(..., operation: <source or logical op>)`.
* If error is `FormatException`: map to `ParsingException`.
* Else: map to `UnexpectedException` with `cause`, `stack`, `devMessage` (should include `source` when provided).

---

## 10. Source label rules

* Provide `source` to every guard.
* String, stable, ASCII, recommended pattern `Feature.Module.Action`.
* Used in fingerprints (`client.dart`), grouping, and dedupe.

---

## 11. Optional features (not required for this workflow)

* Additional context providers (e.g., `UIContextProvider`, `UserContextProvider` as manual‑only).
* Custom sanitizers/filters (`DefaultSanitizer`, `FilterSanitizer`, `RegexValueSanitizer`, `MaxDepthSanitizer`, `TruncatingSanitizer`, `SizeBudgetSanitizer`).
* Outbox flush triggers (`BugReportClient.instance.flush()`).
* `ErrorBoundary` widget for local fallback UI.

---

## 12. Compliance checklist (apply for every feature)

* Repository throws only `BaseException` subclasses.
* Controllers call `guard(...)` with `source`.
* State `error` is a `BaseException` (never a string).
* UI uses `error.userMessage` for display.
* HTTP paths use `ApiException` (or app subclass) with `HttpStatusCodeInfo`.
* Unknowns are wrapped in `UnexpectedException`.
* No business logic depends on report delivery success.

---

## 13. Output stability

* No timestamps, randomness, or environment‑dependent text in this spec.
* Section/order is fixed; ties resolved by full ASCII key.
