OFTR-011: CLI Telemetry
Synced from
outfitter/docs/requirements/OFTR-011-telemetry.md. The repository is the source of truth.
Overview
Section titled “Overview”Outfitter collects a narrow, pseudonymous product-analytics signal for command adoption and reliability. Telemetry must remain controllable, content-free, scope-aware, and unable to affect normal CLI behavior when analytics infrastructure fails.
Requirements
Section titled “Requirements”OFTR-011.1: Consent and Control
Section titled “OFTR-011.1: Consent and Control”- Telemetry MUST default to enabled when no applicable setting exists and MUST print a one-time notice before the first capture.
- Only user and user-local settings MAY explicitly enable telemetry. A false value in user, user-local, project, or project-local settings MUST disable telemetry. Remote and catalog settings MUST NOT enable telemetry.
- Invalid loaded settings MUST fail closed.
OUTFITTER_TELEMETRY=0andDO_NOT_TRACK=1MUST disable capture for the process. CI detection MUST NOT change the effective consent.telemetry.enabledin~/.agents/settings.ymlMUST be the sole persistent user control and MUST be togglable by editing that file. The CLI MUST NOT expose atelemetrycommand.- When consent is disabled, Outfitter MUST automatically delete the pseudonymous installation
identifier. The CLI and Pi setup completion flows MUST mention
telemetry.enabled: falseas the opt-out setting.
OFTR-011.2: Data Minimization
Section titled “OFTR-011.2: Data Minimization”- Outfitter MUST capture only
cli command startedandcli command completed. - Event properties MUST be constructed from the documented allowlist and low-cardinality enums.
- Outfitter MUST NOT capture command arguments, prompts, responses, paths, repository data, agent or profile names, settings, environment values, error details, session identifiers, or child process output.
- Every capture MUST set
$process_person_profileto false, and the PostHog client MUST disable GeoIP enrichment.
OFTR-011.3: Pseudonymous State
Section titled “OFTR-011.3: Pseudonymous State”- The installation identifier MUST be a random UUID stored outside
~/.agentsunder the Outfitter XDG state directory. - A blank
XDG_STATE_HOMEMUST be treated as unset. - The state file MUST be created lazily and MUST record whether the first-run notice was shown.
- User-facing telemetry descriptions MUST consistently call the analytics pseudonymous.
OFTR-011.4: Failure Isolation
Section titled “OFTR-011.4: Failure Isolation”- Analytics failures MUST NOT change CLI stdout, stderr, behavior, or exit status.
- PostHog requests MUST be aborted within the 1000 ms shutdown budget. Request failures and non-success responses MUST be converted to synthetic success responses before the SDK can log or retry them.
- CLI shutdown MUST await the SDK’s bounded shutdown and MUST NOT hold process exit beyond the 1000 ms budget.
- An empty compiled PostHog API key MUST keep telemetry inert without constructing a client, touching telemetry state, or printing a notice.
OFTR-011.5: Executable Boundary
Section titled “OFTR-011.5: Executable Boundary”- Instrumentation MUST occur only at the executable command lifecycle boundary.
- The command name MUST be derived from registered top-level commands, with unrecognized values
mapped to
unknown. - Tests MUST inject telemetry clients and temporary homes so no test can send a production event or touch developer telemetry state when a real API key is compiled.
OFTR-011.6: Continuous Integration
Section titled “OFTR-011.6: Continuous Integration”- A detected CI run MUST use
ci.<vendor-id>as its distinct identifier, where<vendor-id>is the lowercasedci-infovendor ID, orci.unknownwhen no vendor is identified. - A detected CI run MUST NOT read or create persistent telemetry state.
- A detected CI run MUST NOT print the first-run telemetry notice.
- Both telemetry events MUST include
is_ciandci_name.is_ciMUST be a boolean.ci_nameMUST be the lowercasedci-infovendor ID,unknownfor CI without an identified vendor, ornoneoutside CI. CI=false(the exact string) MUST bypass CI detection and use the non-CI identity and state path.