Skip to main content

Module consent

Module consent 

Source
Expand description

Usage-sharing consent (src/asdecided/consent.py) — ADR-041, ADR-086.

The record is JSON under $XDG_CONFIG_HOME/decisions/telemetry.json with the Explorer-preferences posture: a missing/corrupt/non-dict file means no consent, loading never raises, and saving tolerates filesystem trouble silently. The install id is random (secrets.token_hex(16)), minted at opt-in and preserved across off-and-on toggles; the enterprise hard-lock (ADR-086) records a forced-off choice and refuses opt-in until unlocked. The native engine has no sender (ADR-131), so this state is local compatibility data only.

Loading mirrors CPython’s coercions field-by-field: bool(value) truth semantics for the flags and str(value) (including str(None) == "None" and container repr) for the id fields — a present-but-null install_id really does read back as the string None, exactly like the oracle.

This module also carries the shared XDG path builder, the UTC timestamp formatters, and the /dev/urandom token minting that usage.rs reuses for the recorder — the Rust analogue of consent.py sitting outside decided.mcp so everything here stays SDK-free.

Structs§

Consent
The recorded sharing choice; the default is no consent.
ConsentStatus
What decided telemetry status reports.

Constants§

POSTHOG_API_KEY
ADR-131 retires the native PostHog sender. Keep the symbol as an explicit empty kill switch for compatibility with the consent/status contract; no network client or sender exists in this build.

Functions§

consent_path
consent_recorded
consent_recorded() — true once ANY answer (including a decline) has been persisted; the ask-at-most-once gate of the init/quickstart prompt.
consent_status
decline
decline() — persist the default no-consent record, making ask-once true (unlike opt_out, nothing from an existing record is kept).
enterprise_lock
Force the ping off and hard-lock it (ADR-086); ids kept.
enterprise_unlock
Remove the enterprise hard-lock (ADR-086); sharing stays as recorded.
load_consent
Read the consent record; any problem means no consent (never raises). A non-UTF-8 file is a UnicodeDecodeError in the oracle — a ValueError subclass, so it lands in the same tolerant default (unlike the state LOGS, whose readers catch only OSError and crash).
opt_in
Record consent, minting ids only where none exist yet; the enterprise lock is preserved, never cleared here (ADR-086).
opt_out
Withdraw consent; the ids are kept so a later opt-in stays continuous.
save_consent
Persist the record: json.dumps(asdict(consent), indent=2) + "\n" in dataclass field order; tolerates filesystem trouble silently.