Docs: privacy.md lists every usage event; release builds get the key (#238)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-15 01:07:28 -04:00
1 parent 31bc886c7a
commit db80b75814
5 files changed
+107 -5

No files matched your search

+8
View File
@@ -97,6 +97,8 @@ jobs:
- name: Build, sign, notarize and package (the dmg is mounted and checked)
id: package
env:
# The analytics project key (docs/privacy.md), built in; never printed.
FIELDCRAFT_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
@@ -139,6 +141,9 @@ jobs:
cargo install --locked --version "$CARGO_DEB_VERSION" cargo-deb
cargo install --locked --version "$CARGO_GENERATE_RPM_VERSION" cargo-generate-rpm
- name: Build and package (tar.gz, AppImage, deb, rpm)
env:
# The analytics project key (docs/privacy.md), built in; never printed.
FIELDCRAFT_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
run: packaging/linux/package.sh
- name: Check the packages
run: |
@@ -211,6 +216,9 @@ jobs:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Build and package (zip)
shell: pwsh
env:
# The analytics project key (docs/privacy.md), built in; never printed.
FIELDCRAFT_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
run: ./packaging/windows/package.ps1
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
+5 -2
View File
@@ -137,8 +137,11 @@ Rust 1.95 or later, with the `wasm32-unknown-unknown` target for `cargo xtask ci
## Privacy
FieldCraft sends nothing anywhere on its own: no analytics, no telemetry, no automatic crash
upload. Crash reports and the log stay on your computer; Help › Report a Bug opens a GitHub issue
FieldCraft sends nothing until you agree. The first start asks once whether to share anonymous
usage (which tools you use, nothing from your models); Help › Settings… changes it, and
`FIELDCRAFT_TELEMETRY=0` turns it off. File names, paths, geometry, model contents, parameter
values and messages are never sent: [docs/privacy.md](docs/privacy.md) lists every event and
property. Crash reports and the log stay on your computer; Help › Report a Bug opens a GitHub issue
you review and submit yourself, with your session or model attached only if you tick them
([docs/crash-reports.md](docs/crash-reports.md)).
+3 -3
View File
@@ -2,9 +2,9 @@
## Privacy
FieldCraft sends nothing anywhere on its own: no analytics, no background telemetry, no
automatic crash upload. Crash reports and the log stay on this computer. The only way anything
leaves it is **Help › Report a Bug** (or **Report It…** after a crash), which opens a GitHub issue
No crash report, log line or model is uploaded automatically. Crash reports and the log stay on
this computer (anonymous usage, if you agreed to share it, never carries them: see
[privacy.md](privacy.md)). The only way they leave it is **Help › Report a Bug** (or **Report It…** after a crash), which opens a GitHub issue
form in your browser; you read it there and submit it, or not.
What a bug report carries:
+84
View File
@@ -0,0 +1,84 @@
# Privacy and anonymous usage
FieldCraft can share **anonymous usage** with its developers: which tools are used, where people
get stuck and how far they get from a design to results. It is **off until you agree**. The first
time the app starts it asks once:
> Help improve FieldCraft by sharing anonymous usage: which tools you use, nothing from your models.
**Share Anonymous Usage** turns it on, **Don't Share** (or closing the question) leaves it off.
Change it any time in **Help › Settings… › Privacy**, which also has **Include scripts and AI
agents (MCP)**: commands run by scripts, the control channel and AI agents are counted apart from
yours (`from`), and this leaves them out.
Crash reports and the log never leave your computer on their own; Help › Report a Bug sends only
what you submit yourself ([crash-reports.md](crash-reports.md)).
## Never sent
File names or paths, geometry, meshes, model contents, parameter values (sizes, materials,
loads…), names you give things, error messages, or anything else you typed. The events below are
built from FieldCraft's own lists (its command ids, sample names and requirement names) and
durations, so they cannot carry any of it; a test runs a scripted session and fails if a payload
holds anything else.
## When nothing is sent
- until you agree, and after you turn it off (what was waiting is dropped);
- in builds without an analytics key: everything built from source, development and fork builds.
Only the release builds have one;
- with `FIELDCRAFT_TELEMETRY=0` (or `false`, `off`, `no`) in the environment;
- in runs driven by automation (`--control`) and in CI (`CI` set), unless
`FIELDCRAFT_TELEMETRY=1` asks for it;
- `fieldcraft-cli` and the MCP server never send anything themselves; the app counts the
commands they send it.
## Where it goes
[PostHog](https://posthog.com) Cloud, EU region (`https://eu.i.posthog.com`), a batch of events
every 30 seconds and when the window closes, on a background thread (the web build uses `fetch`).
A batch that cannot be sent (offline, a slow network) is dropped; at most 1000 events wait. Each
event goes with `$process_person_profile: false` (no person profile is built) and
`$geoip_disable: true` (no location is derived from the connection's IP address).
`FIELDCRAFT_TELEMETRY_HOST` sends to another host instead (to check what is sent against a local
listener).
## What is sent
Every event has these properties:
| Property | Value |
|---|---|
| `distinct_id` | a random id made for this install when you agree (a UUID), kept in the preferences; nothing about the computer or you |
| `app_version` | FieldCraft's version, `0.5.8` |
| `platform` | `desktop` or `web` |
| `os` | `macos`, `linux`, `windows`, or `web` |
| `arch` | `aarch64`, `x86_64`, or `wasm32` |
| `$process_person_profile` | `false` |
| `$geoip_disable` | `true` |
The events:
| Event | Properties | When |
|---|---|---|
| `app_started` | — | the app starts with sharing on, or you turn it on |
| `app_closed` | `duration_s`: seconds since `app_started` | the window closes (the page is closed or left) |
| `command_run` | `command`: the command's id (`mesh.tet.generate`); `kind`: `model` or `session`; `duration_ms`; `ok`: whether it succeeded; `error` (when it failed): the class of the error, one of `unknown_command`, `params`, `model`, `geometry`, `mesh`, `file`, `deck`, `solver`, `explicit`, `fluid`, `unavailable`, `internal`; `from`: `ui` (a click, a form, a menu), `palette` (the command search or command line), `script` (a script or the control channel) or `mcp` (an AI agent) | a command ends; a command run by another (a script's steps inside it) is not counted on its own |
| `milestone` | `name`: `design_opened` (a design, mesh or model opened), `meshed` (a mesher made elements), `solved` (a solve finished), `results_viewed` (results shown) | the first time in a run |
| `sample_opened` | `name`: the sample's name (`cantilever`) | a sample opens |
| `form_cancelled` | `command`: the form's command id | a command's form closes without running it |
| `unavailable_clicked` | `command`: the command id; `missing`: what the model lacks, by requirement name (`material`, `step`, …) | a command is clicked before the model has what it needs |
A `command_run` as sent:
```json
{"event": "command_run", "distinct_id": "5f0c…-…", "properties": {"command": "solve.run", "kind": "model", "duration_ms": 412, "ok": true, "from": "ui", "app_version": "0.5.8", "platform": "desktop", "os": "macos", "arch": "aarch64", "$process_person_profile": false, "$geoip_disable": true}}
```
## For developers
The events and the policy are `fieldcraft_engine::usage`; the consent question and the settings
are `crates/ui-egui/src/privacy.rs`; the desktop sender is `apps/fieldcraft/src/usage.rs`, the
web one `apps/fieldcraft-web/src/usage.rs`. The PostHog project key is the build-time variable
`FIELDCRAFT_POSTHOG_KEY`, which the release workflow sets from the repository secret
`POSTHOG_KEY`; it is an ingest-only key. A new event or property is added here first.
+7
View File
@@ -60,6 +60,13 @@ in the keychain.
SmartScreen warns about an unsigned download (More info › Run anyway) until a code-signing
certificate is added.
## Usage analytics key
The release builds (macOS, Linux and Windows jobs) build in the PostHog project key from the
repository secret `POSTHOG_KEY` as `FIELDCRAFT_POSTHOG_KEY` ([privacy.md](privacy.md)). Without the
secret the builds ask nothing and send nothing, as local and fork builds do. The web build on
Pages has no key.
## Choose and prepare the version
1. Look at the previous published release (`gh release list -R jyviko/fieldcraft`) and the