K2GO-391 feat(app-backstop): active user report when the disk guard contains a problem - #552
Merged
Merged
Conversation
…ontains a problem The disk guard already reports to GlitchTip automatically. This adds the ACTIVE channel: when the guard handles a meaningful situation, it tells the user and offers a report the user sends via email -- not only waiting on GlitchTip. The guard runs in WatchdogService (no Activity), and the feedback email needs one. So notifyUser posts a notification whose tap opens LibraryActivity carrying a pre-filled diagnostic (EXTRA_DISK_GUARD_REPORT); LibraryActivity.onResume hands it to the existing feedback flow (FeedbackFab.sendFeedback, FeedbackType.BUG), the same pre-filled pattern the install-failed report uses (ADFA-5119). The extra is consumed on first resume so it never re-fires. Fired on a meaningful containment only: the escalation (box stopped) and a recurring-firehose contain. The routine low-disk reap does not notify (no nag); it is still recorded to GlitchTip. Each event kind uses its own notification id so one does not replace the other. Diagnostic carries action, reaped, reclaimed bytes, trip/streak and current free bytes; the feedback flow adds the standard envelope (version, device, ABI). New strings in strings_untranslated.xml. Authority: controller/docs/ADR-386-unattended-disk-containment.md section 12.
…e + firehose paths)
Make the report self-diagnosing without the session context, and keep it from
ever carrying raw logs.
- source field (low_disk | firehose_signal | debug) in both channels (Sentry +
email). It disambiguates trip_or_streak: a debug run reads -1, a real firehose
reads its server streak, a low-disk trip reads its count. No more cryptic -1.
- firehose_paths: which log(s) were the culprit. FirehoseSignal now parses the
paths the endpoint already returns; FirehoseSignalSource caps them (count and
length), so a pathological signal cannot bloat the report.
- Bounded by design: the report is a pointer plus a short summary, never log
content. The firehose log stays on the device; the only attachment is the
feedback screenshot (~100 KB). So a runaway log can never break the email/Sentry
pipe. Documented in ADR-386 section 7 ("bounded by design").
formatPaths is the one shared path formatter (report + email). FirehoseSignalTest
gains a paths case (null -> empty). Domain tests green (Escalation 5, Policy 4,
FirehoseSignal 6).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The active report channel for the disk guard, plus its localization. When the
guard handles a meaningful situation, it tells the user and offers a report the
user sends via email -- not only the automatic GlitchTip report. The report is
self-diagnosing and bounded.
Why
The operator should understand what the guardian did and raise it in one tap,
without knowing internals. Developers get a real field report actively, not only
by waiting on GlitchTip. And the report can never grow large enough to break the
reporting pipe.
How
The guard runs in WatchdogService (no Activity) and the email flow needs one, so
notifyUser posts a notification whose tap opens LibraryActivity with a pre-filled
diagnostic (EXTRA_DISK_GUARD_REPORT). LibraryActivity.onResume hands it to
FeedbackFab.sendFeedback(..., FeedbackType.BUG, msg) -- the ADFA-5119 pre-filled
pattern -- and consumes the extra so it never re-fires. Fires on the escalation
and a recurring-firehose contain only (routine low-disk reap does not notify);
distinct notification ids per kind.
The report is self-diagnosing and bounded, in both the email and the automatic
GlitchTip event:
(a debug run is -1, a real firehose is its server streak).
capped in count and length (FirehoseSignalSource); never log content. The
runaway log stays on the device.
never bloat the report and break the email/Sentry pipe.
Authority: ADR-386 sections 7 and 12.
l10n
The disk-guard alert strings shipped parked in strings_untranslated.xml. They are
now migrated to a translated per-feature file: values/strings_diskguard.xml plus a
per-locale file for all 33 locales. Translations are machine-generated, marked for
human review in each file header ("K2Go" kept as a product name). The tracking
file is now empty.
Verification
Compiles clean; two-pass review applied (fixed a stale Javadoc and a
notification-id collision; the report path is bounded by design). Domain tests
green (DiskGuardEscalation 5, DiskGuardPolicy 4, FirehoseSignal 6).
./gradlew :app:lintDebug BUILD SUCCESSFUL (MissingTranslation clean). Device-
verified end to end on a OnePlus 7T (HD1901): the debug firehose hook with a
growing .log posted the notification; tapping it opened LibraryActivity and
composed the pre-filled feedback email (subject "[K2Go] Bug -- disk-guard", body
with the full envelope plus source/action/reaped/reclaimed_bytes/trip_or_streak/
free_bytes), with the screenshot attached. The box reaped and relaunched
(restart-to-keep-alive).