Error Reporting (all modules)
Relatório de erros para todos os módulos Koder: toggle "Relatório automático" obrigatório em Settings (default OFF, ausência = desabilitado), botão "Reportar problema" sempre visível, grupos de dados A–G, contrato de privacidade (o que nunca capturar), retenção e acesso. Implementação: KoderErrorReporter + KoderReportButton (engines/sdk/koder_kit). Backend: foundation/reporter. Nunca implementar localmente.
Error Reporting Spec — v0.1
Normative spec derived from
docs/rfcs/RFC-001-error-reporting-framework.md. Implementação:foundation/reporter+engines/sdk/koder_kit (KoderErrorReporter).
Scope
Applies to *ll Koder modules*on *ll platforms* Flutter mobile, Flutter desktop, TV (JS/React), web apps, Go backend services, and any future SDK binding.
1 — MUST: expose "Report a problem" in Settings
Every module that has a user-facing Settings screen *ust*expose a "Report a problem" / "Reportar um problema" action. This action opens the manual report flow provided by KoderReportButton from engines/sdk/koder_kit.
This button is *lways visible* regardless of any other error reporting toggle.
2 — MUST: expose "Automatic error reporting" toggle in Settings
Every user-facing module *ust*expose an "Automatic error reporting" / "Relatório automático de erros" toggle.
*efault OFF* the toggle must be *nactive by default on every fresh install* The absence of a stored preference means disabled:
// Dart / Flutter
final enabled = prefs.getBool('error_reporting') ?? false; // absent == OFF// Go services — operator-controlled, not user-controlled
enabled := os.Getenv("KODER_ERROR_REPORTING") == "true"// Web / TV
const enabled = localStorage.getItem('error_reporting') === 'true';The toggle lives in *ettings → Privacy → Error Reporting*
3 — MUST: expose granular child toggles when auto-report is ON
When autoreport is enabled, two additional optin toggles MUST be shown (both default OFF):
- *Include navigation history"*— enables Group E (breadcrumbs).
- *Include device state"*— enables Group F (memory, battery, storage).
final breadcrumbs = prefs.getBool('error_reporting_breadcrumbs') ?? false;
final deviceState = prefs.getBool('error_reporting_device_state') ?? false;Child toggles are hidden when the parent toggle is OFF.
4 — MUST: use engines/sdk/koder_kit — never implement locally
Before implementing any error reporting logic, check engines/sdk/koder_kit for KoderErrorReporter and KoderReportButton. All modules use these; no module reimplements capture, sanitization, or submission logic locally.
5 — MUST: submit only to foundation/reporter
All reports go to https://reporter.koder.dev/api/v1/reports. No module submits error data to any other endpoint.
6 — Data groups and capture policy
Always captured (Groups A–D)
No user consent required beyond accepting the app's privacy policy.
| Group | Content |
|---|---|
| A — Report identity | report_id, reported_at, occurred_at, report_type |
| B — Module identity | app_slug, app_version, build_number, distribution_channel, build_type |
| C — Platform | platform, os_version, device_class, device_model_hash, architecture, locale, timezone_offset |
| D — Error context | error_id, error_category, severity, stack_trace (sanitized), error_message_raw, is_fatal, recurrence_in_session, fingerprint |
Opt-in (Groups E–F)
Requires the corresponding child toggle to be ON.
| Group | Content | Toggle key |
|---|---|---|
| E — Breadcrumbs | current_route, breadcrumbs, last_action, app_uptime_seconds |
error_reporting_breadcrumbs |
| F — Device state | network_state, memory_available_mb, storage_available_mb, battery_level, battery_charging, app_in_foreground |
error_reporting_device_state |
Manual only (Group G)
Never sent automatically. Only via explicit user action in the report dialog.
| Field | Consent required |
|---|---|
user_description |
Implicit (user typed and tapped Send) |
user_contact_email |
Explicit (user filled in optional field) |
screenshot_data |
Explicit (separate "Attach screenshot" tap + consent dialog) |
7 — Privacy: what is NEVER captured
The following are unconditionally prohibited. The SDK enforces this; foundation/reporter applies a second PII scrub as a defenseindepth layer.
| Category | Examples |
|---|---|
| User identity data | Names, emails, phone numbers, CPF, RG |
| User-generated content | Audio recordings, video, documents, messages, transcriptions |
| Input events | Keyboard events, key sequences, clipboard contents |
| Session replay | Screen recordings, video of UI, gesture sequences |
| Media device access | Microphone, camera — the reporter SDK has no API access to these |
| Contact/calendar data | Address book, calendar entries, call history |
| Real device identifiers | IMEI, Android ID, IDFA, serial number |
| Raw IP addresses | Discarded server-side after GeoIP resolution |
| Absolute paths with usernames | Sanitized to relative paths before transmission |
| Tokens and credentials | Scrubbed by regex before transmission |
8 — Stack trace sanitization (mandatory)
Applied by the SDK before serialization:
- Absolute paths → relative:
/home/username/...→koder/... - Query parameters stripped from any URL in the trace.
- Regex redaction: email addresses, phone numbers, long UUIDs in user-visible positions.
- Local variable values are NOT included unless the module explicitly enables variable capture (requires a separate spec amendment).
9 — Backend services (kdb, koderjet, koderid, etc.)
Groups A, B, C (minus mobile-specific fields), and D apply. Groups E/F are replaced by:
| Field | Description |
|---|---|
request_id |
Trace ID of the request that failed |
operation |
HTTP method + path template |
http_status |
Integer |
upstream_dependency |
Service name that caused the failure |
retry_count |
Integer |
response_time_ms |
Integer |
The toggle for backend services is an env var / koder.toml entry, not a user-facing UI toggle. Default is OFF. The operator (not the user) decides.
10 — Deterministic audit checks
/k-housekeep verifies per module:
- Settings screen contains a widget/key referencing
error_reportingpreference. prefs.getBool('error_reporting') ?? false(or equivalent absentmeansoff pattern) is the sole read point — no hard-codedtruedefault.KoderReportButtonis present in Settings regardless of the auto-report toggle state.- No module captures keyboard events, screen content, media device streams, or raw device identifiers.
- All report submissions target
https://reporter.koder.dev/api/v1.
File: meta/docs/stack/specs/errors/reporting.kmd
Trigger: read this spec before implementing error reporting, the "Report a problem" button, auto-report toggles, or any data capture related to errors in any Koder module.