SIGN IN SIGN UP

feat(telemetry): foundation CLI + schema-guard + off-by-default proof (#1736)

* feat(telemetry): add consent CLI surface for maintainer-share opt-in

Adds the foundation CLI commands described in RFC #1719:

- bernstein telemetry enable --share-with-maintainer: prints the event
  schema and redaction list, requires confirmation, and persists
  share_with_maintainer = true to $XDG_CONFIG_HOME/bernstein/telemetry.toml.
- bernstein telemetry disable: reverts the flag.
- bernstein telemetry tail [-n N]: prints the next N events that would
  be sent, offline, from a new in-process side-channel preview ring buffer.

The existing telemetry on/off/status/export/probe surface is unchanged.
telemetry status grows three new lines covering the share flag value,
its source provenance, and the resolved DSN.

The flag lives in a separate TOML file and gates an additive opt-in
path. The shipped package still hardcodes no maintainer endpoint URL.

* docs(telemetry): document maintainer-share consent flow

Adds docs/observability/telemetry-share.md covering:

- The consent flow for the share_with_maintainer flag.
- Env-var and TOML precedence (DO_NOT_TRACK, BERNSTEIN_TELEMETRY_SHARE).
- The exact event schema and redaction list that drive the disclosure.
- How to audit offline via bernstein telemetry tail.
- Three equivalent ways to revoke consent.

Links the new page from docs/observability/side-channel.md so operators
reviewing the operator-controlled side channel see the additive consent
surface in context.

* test(telemetry): schema-guard requires redaction decision per event field

Introspects every Payload dataclass in core/telemetry/events.py and
asserts each field is either listed in SAFE_PRIMITIVE_FIELDS (the
explicit allowlist of safe primitives shown in the consent disclosure)
or has an entry in REDACTION_RULES describing how it is sanitised.

Adding a new payload class without registering it in PAYLOAD_CLASSES
also fails, so the schema cannot silently grow.

* test(telemetry): presence-or-absence proof for share-flag off-by-default

Asserts the RFC #1719 invariant: with share_with_maintainer unset, the
package sends nothing on the maintainer-share path, under three DSN
configurations (unset, syntactically invalid, and broken-shape).

respx intercepts every outbound httpx call; the catch-all route is asserted
to remain uncalled. An independent canary inside the test confirms respx
is the active transport so the assertion cannot pass trivially.

Complementary checks cover:

- the env-var precedence (BERNSTEIN_TELEMETRY_SHARE=0 overrides file=true)
- the universal DO_NOT_TRACK=1 override
- the package not baking in a default maintainer URL
- resolving consent never creates the TOML file as a side effect

Also adds CLI snapshot coverage for the new enable / disable / tail
subcommands.
C
chernistry committed
759daa9035803cb29ffa3fedf02c9117feae6a4b
Parent: 7249540
Committed by GitHub <noreply@github.com> on 5/20/2026, 1:44:25 PM