Frostyard images and apps can send short problem reports, so we can find and fix faults. Reporting is off until you turn it on. This page says what a report holds, where it goes, how long we keep it, and how to have it deleted.
Status: ChairLift v0.15.0 and later sends reports on Snow, Snowfield and Sundog after you turn reporting on. Those images get it with the next image release. On Floe, snosi-health sends reports after an administrator turns reporting on.
What reports are for
Reports tell us which updates fail, which services break, which Frostyard apps hit errors, and which versions are in use. Each kind of report and its purpose is in What is sent.
Turn reporting on or off
Nothing is sent until you turn reporting on. When you turn it off, sending stops at once. The controls are:
- Snow, Snowfield and Sundog: ChairLift's Problems page has a Send problem reports switch. On Snow and Snowfield, ChairLift's first-run setup can also ask you, with the switch off. Each user of the computer decides for themselves. In Ask each time, ChairLift shows you the exact report before it sends it. In Send automatically, it sends without asking, and its Sent reports list shows the 50 newest reports it sent.
- Floe: an administrator runs
sudo snosi-health reporting onoroff.snosi-health reporting statusshows the choice.snosi-health send --dry-runprints the exact reports without sending them.
Frostyard apps never send anything themselves. They write problems to the journal on your computer. ChairLift on a desktop, or snosi-health on Floe, is the only program that sends. A computer that does not run a Frostyard image sends nothing.
If a new version of the report format adds a kind of report or a field, sending stops until you agree again.
What is sent
Every report has the fields below, and then the fields of its kind. Every value is a fixed choice, a number in a range, a version, or a name from a fixed list. No field holds free text. The machine-readable format is /schemas/problem-report/v1.json.
| Field | What it holds | Values |
|---|---|---|
schema | The schema version of the report. | frostyard.problem/1 |
report_id | A random ID, made new for each report. It links nothing else. Give it to us to have that report deleted. | |
week | The ISO week the problem happened, or the week a count is sent. Never a date or a time. | |
image.id | Which image the computer runs. | snow, snowfield, sundog, floe |
image.version | The image version, a 14-digit build timestamp. | |
secure | Whether the computer runs the secure-boot variant of the image. | |
client | The program that sent the report and its version: ChairLift on desktops, snosi-health on Floe. | |
kind | What kind of problem the report is about. Each kind is described below. | unit_failed, update_stage_failed, booted_older_image, sysext_update_failed, tpm_unlock, integrity_error, crash, app_problem, count |
A system service failed unit_failed
Finds image services that break after an update. Only services that ship in the image are reported, never one you added.
| Field | What it holds | Values |
|---|---|---|
unit | The service name, with any instance part removed (user@1000.service becomes user@.service). | |
result | How it failed. | exit-code, signal, timeout, core-dump, start-limit-hit, other |
shipped | Always true: the service ships in the image. | true |
An update could not be prepared update_stage_failed
Finds updates that never get ready to install.
| Field | What it holds | Values |
|---|---|---|
target_version | The image version the update tried to prepare. | |
error_class | Why it failed, as a broad class. | network, registry, signature, disk_space, lock, other |
bootc_version | The version of bootc, the tool that prepares updates. |
The computer went back to an older image booted_older_image
Finds updates that make people go back to the previous image.
| Field | What it holds | Values |
|---|---|---|
newer_version | The newer image version that was not kept. | |
how | How the older image was chosen. | manual_rollback, boot_menu, unknown, other |
A system extension update failed sysext_update_failed
Finds system extensions that fail to update. Extensions you added yourself are never reported.
| Field | What it holds | Values |
|---|---|---|
feature | The extension name, from the image or the Frostyard catalog. | |
version | The extension version. | |
outcome | What happened to the update. | failed, held_by_rollback, needs_image, skipped_unreachable, skipped_busy, other |
error_class (optional) | Why it failed, as a broad class. | network, http_status, signature, checksum, disk_space, link, config, other |
The disk did not unlock on the first try tpm_unlock
Finds releases that break automatic disk unlock with the TPM. A clean first-try unlock is not recorded.
| Field | What it holds | Values |
|---|---|---|
outcome | How the disk was unlocked in the end. | ok_after_retry, recovery_key, passphrase, other |
tpm_rc | The TPM's reason for refusing, as a broad class. | PCR_CHANGED, POLICY_FAIL, LOCKOUT, other |
retries | How many retries it took, from 0 to 10. |
A file integrity check failed integrity_error
Finds corrupted files or a bad build. File names are never sent.
| Field | What it holds | Values |
|---|---|---|
subsystem | Which integrity check failed. | composefs, fs-verity, dm-verity, other |
count | How many errors, in a range. | 1, 2-10, >10 |
A program crashed crash
Not sent yet. The format defines crash reports, but the first releases that send reports keep crashes on your computer; a later release adds them. Then they will find crashes of programs in the image. Only programs under /usr will be reported; a crash of a Flatpak app stays on your computer. The core dump, the command line and the environment are never sent.
| Field | What it holds | Values |
|---|---|---|
exe | The program's file name without its folder. | |
package (optional) | The Debian package that holds the program. | |
package_version (optional) | The version of that package. | |
signal | The signal that stopped the program. | SIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE, SIGTRAP, SIGSYS, other |
A Frostyard app hit an internal error app_problem
Finds bugs in Frostyard's own apps. The error message stays on your computer.
| Field | What it holds | Values |
|---|---|---|
app_id | Which Frostyard app. | org.frostyard.ChairLift, org.frostyard.nsl, org.frostyard.intuneme, org.frostyard.pilothouse, org.frostyard.Frostmail, org.frostyard.Frostnotes, org.frostyard.Frostread |
app_version | The app's release version. | |
runtime | The language the app part is written in. | go, rust |
component | Which part of the app. | daemon, cli, gui, shell, other |
class | A crash of the app (panic) or a known error. | panic, error |
code (optional) | A fixed error code from the app's source, such as store.migrate_failed. Sent only for errors. | |
frames (optional) | For a Go panic: up to 32 function names from Frostyard code, the Go standard library, and the go-imap fork that Frostmail uses. No file paths, no arguments. Other functions show as other. | |
location (optional) | For a Rust panic: the source file and line in Frostyard's code, such as src/store.rs:42. |
Weekly count count
Counts the users who turned reporting on (on Floe, the computer), to see which versions are in use and whether updates arrive. Sent at most once a week. Counts are approximate: 2 users who turn reporting on at 1 desktop count 2 times.
| Field | What it holds | Values |
|---|---|---|
install_age | How long ago the system was installed, in a range. | <1w, <1m, <6m, >=6m |
channel | Whether the computer follows the latest image. | latest, other |
What is never sent
- No machine ID, boot ID, account, user name, host name or cookie.
- No error message, panic message, log text, command line or environment.
- No path, name or content of your files, and no core dump. When crash reports start, a crash report will name only the program that crashed and its package. A Rust app problem names a source file of Frostyard's own code.
- No date or time finer than a week. The intake and GlitchTip record the time a report arrives.
- Nothing about services or extensions that you added yourself.
Your IP address
Your IP address is personal data. It reaches Cloudflare, which carries the report to report.frostyard.org for us as our processor, under its data processing agreement. The intake uses the address only to limit each address to 10 requests a minute, with a short-lived counter. It does not store, log or forward the address, and it stores no key made from it. The server that keeps reports never receives it: the proxy in front of that server removes the forwarding headers and keeps no log.
Cloudflare's own security features can record the address of a request that they block or challenge, in Cloudflare's security events.
Where reports go and how long we keep them
- Reports: the intake checks each report against the format, then forwards each problem report to GlitchTip, an error tracker on a server in the United States. The weekly count is not forwarded. GlitchTip keeps reports for 72 days. Its nightly cleanup and 7 days of backup snapshots can keep parts of a report up to about 88 days in all. Every report is deleted within 90 days. GlitchTip keeps each value it has seen in a report field, such as an image version or a program name, with no link to any report and with no end date.
- Counts for the statistics: for each accepted report, the intake also writes 1 data point to Cloudflare Workers Analytics Engine. A data point holds only values from the report, such as the kind, the image and its version. It holds no
report_idand no IP address. Cloudflare records the time it writes each point and keeps the points for about 3 months. - Weekly statistics: totals for each week, kept in Cloudflare Workers KV with no end date, and published.
- Public bug reports: GitHub issues about faults in Frostyard code, kept with no end date. They hold only checked values, no report. See Public bug reports.
Public statistics
We publish weekly totals on the statistics page. A number from 1 to 4 is never published, and neither is a number that would let you work one out from the totals. We never publish single reports. The 1-to-4 rule covers the statistics: a public bug report holds no count, but it exists only because 1 or more reports came in.
Public bug reports
When reports show a fault in Frostyard code, a job can open a public GitHub issue for it, with the label problem-report, in the repository of the app or image that has the fault. Anyone can read these issues: list every public bug report. The job runs at most once a day and opens at most 1 issue for each problem. crash and count reports never open an issue.
Before the job publishes a value, it finds that value in a public source of Frostyard: a release tag, the source code at that tag, a published image tag, the published extension index, or the job's fixed list of Frostyard services and extensions. A value that fails its check is never published.
What an issue holds
- The kind and the class of the problem.
- The newest version that the job checked: the app version for an app problem, else each image with its newest image version. Never a list of versions.
- The fields of its kind in the table below, and no other field.
- A problem key: a short hash of the published values only.
- The numbers of the matching issues in our GlitchTip. These are GlitchTip's own issue numbers, not report IDs.
- Later comments from the job hold only fixed text, a marker, and the fix releases and versions that it checked.
| Kind | Fields in the issue |
|---|---|
app_problem | app_id, runtime, component, and code (class error) or frames or location (class panic) |
unit_failed | unit, result |
update_stage_failed | error_class, target_version |
booted_older_image | how, newer_version |
sysext_update_failed | feature, outcome, error_class if the report has it, and the newest checked extension version, shown as feature_version, if there is one |
tpm_unlock | outcome, tpm_rc, the variant |
integrity_error | subsystem, the variant |
A Go frame of another module shows only its top package name. The variant tells if the image is the standard or the secure-boot image (the report's secure). Only tpm_unlock and integrity_error show it.
What an issue never holds
No issue, comment or status of the job holds:
- a
report_id, an event ID, aweekor aclient; - any count: no number of reports, no
countbucket, noretries; - any day;
bootc_version,shipped, orsecureoutside the 2 kinds above;- a host name, a user name, a path on your computer, or free text.
What an issue still tells
An issue tells that 1 or more computers with reporting turned on sent a report with these values. Its creation time tells about when the first report came. A rare image and version can point to the few computers that run it.
Which faults are filed
The job files only faults that our GlitchTip first saw on or after , 00:00 UTC. A fault first seen before then is never filed. If you turned reporting on before this section was published, you are not asked again: this section is the notice. You can turn reporting off at any time.
Deletion and turning reporting off
Deleting a report, or turning reporting off, does not remove, change or close an issue. An issue holds no identifier of a report, and only values that exist in Frostyard's public source.
Your rights
- Consent. Consent is the legal basis for reports (GDPR Article 6(1)(a)). You can withdraw it at any time: turn reporting off.
- See what was sent. ChairLift's Sent reports list shows the 50 newest reports it sent, each with its
report_id. By default, ChairLift keeps thereport_idof up to 500 sent reports in~/.local/state/chairlift/reports.json. On Floe, the list is/var/lib/snosi-health/sent.jsonl. A send run that posts at least 1 report and does not stop early drops the entries older than 90 days. Any other run drops nothing. A run that starts after reporting is turned off drops nothing. Only a run already in progress can still finish its cleanup. After that, the file keeps its entries until an administrator deletes it. (snosi ADR-0030). - Delete a report. Send us its
report_idand we delete that report. GlitchTip stores each report under itsreport_id, so we can find it. Backup snapshots keep it at most 7 more days. A deleted report stays in the statistics data points and the weekly totals, which hold noreport_id. A public bug report also stays. Without thereport_idwe cannot tell which report is yours, because reports hold no identifier (GDPR Article 11). - Complain. You can complain to a data protection supervisory authority.
- No automated decisions. Reports are not used to make any decision about you.
Who is responsible
Controller: Frostyard Privacy Admin
Contact for questions and deletion requests: privacy@frostyard.org
Transfers outside the EU
Reports are kept in the United States. Cloudflare processes requests on its global network, under its data processing agreement and the EU–US Data Privacy Framework.
Source
Every part of reporting is open source.
- The decision: frostyard/core ADR-0069: local first, opt-in, one sender per computer.
- Public bug reports: frostyard/core ADR-0074, at the commit that accepted it: which values of a fault may appear in a public issue.
- The triage job: frostyard/problem-intake: how the job checks each value, files an issue, and follows the fix.
- Every public bug report: GitHub search: org:frostyard label:problem-report.
- The report format: frostyard/core: every field, every value, and the rules for new versions.
- The app library: frostyard/std: the Go package that writes app problems to the local journal. The Rust crate is in rust/.
- The collector: frostyard/snosi: snosi-health, which lists system problems and sends them on Floe.
- The Floe sender: frostyard/snosi ADR-0030: how Floe sends reports after an administrator agrees.
- ChairLift: frostyard/chairlift: the Problems page and the desktop sender.
- The intake: frostyard/problem-intake: the service at report.frostyard.org that checks reports and drops your IP address.
- The statistics: frostyard/problem-intake: how the weekly statistics are counted and which numbers are hidden.
- Retention and deletion: frostyard/problem-intake: the retention limit, the snapshots, and how 1 report is deleted.
The history of this page is in frostyard/frostyard-org.