---
since: 1.1.1
---
# Telemetry
gitaiflow includes optional anonymous usage telemetry. It is designed to help maintainers understand how gitaiflow is being used without collecting repository contents, source-code diffs, commit messages, or other Git content.
**Telemetry is off by default.**
You can use gitaiflow normally without sending telemetry. If you choose to enable it, only a small, documented set of operational fields is sent to the telemetry endpoint.
## What telemetry does
Telemetry answers questions such as:
- Which gitaiflow version is being used?
- Which AI provider and model are being used?
- Are users primarily analyzing files or directories?
- How many files are typically changed?
- How long do runs take?
- What are the approximate input/output token counts?
- How often do runs succeed or fail?
- Which operating systems are represented?
It does **not** collect your repository or the contents of your changes.
## Telemetry is optional
There are three relevant states:
| State | Behavior |
|---|---|
| **Not yet configured** | An interactive terminal run asks whether you want to enable anonymous telemetry. |
| **Enabled** | Normal gitaiflow runs send the documented anonymous telemetry payload. |
| **Disabled** | Normal gitaiflow runs do not send telemetry. |
For non-interactive environments such as CI, redirected output, or piped execution, gitaiflow does not display an interactive consent prompt and defaults telemetry to **off** unless `GITAIFLOW_TELEMETRY` explicitly overrides it.
## How telemetry works
```mermaid
flowchart TD
A["Run gitaiflow"] --> B["Generate local summary"]
B --> C["Write local usage record"]
C --> D{"Telemetry enabled?"}
D -->|No| E["Stop
Nothing sent remotely"]
D -->|Yes| F["Build fixed telemetry payload"]
F --> G["Send HTTPS event"]
G --> H["Telemetry receiver"]
I["Repository / diff / Git data"] -.-> J["Never included"]
J -.-> F
classDef local fill:#e8f7f1,stroke:#2b9a78,stroke-width:2px,color:#174d3d;
classDef decision fill:#fff4df,stroke:#d59a2a,stroke-width:2px,color:#5c420b;
classDef external fill:#eeeaff,stroke:#7957c7,stroke-width:2px,color:#382568;
classDef blocked fill:#fff0f0,stroke:#d64545,stroke-width:2px,color:#5c2020;
class A,B,C,E,F local;
class D decision;
class G,H external;
class I,J blocked;
```
The important boundary is:
> **Your repository data stays local to gitaiflow. Telemetry is a separate, opt-in operational event.**
---
# Managing Telemetry Consent
## Enable telemetry
To permanently enable telemetry on the machine:
```bash
gitaiflow --telemetry enable
```
You should see:
```text
[TELEMETRY] Enabled.
```
This stores your consent decision locally so you do not need to answer the prompt on every run.
## Disable telemetry
To permanently disable telemetry:
```bash
gitaiflow --telemetry disable
```
You should see:
```text
[TELEMETRY] Disabled.
```
Disabling telemetry prevents subsequent normal summary runs from sending telemetry.
## Check the current status
```bash
gitaiflow --telemetry status
```
Examples:
```text
Not yet set -- you'll be asked the next time gitaiflow runs interactively, or you can set it now with `gitaiflow --telemetry enable` / `--telemetry disable`.
```
or:
```text
Enabled (saved in ~/.gitaiflow_telemetry_consent, last confirmed on version 1.0.6 at 2026-08-19T14:32:07+05:30).
```
If an environment-variable override is active, the status reports that it applies only to the current process/session.
## View consent history
gitaiflow keeps a local history of explicit consent changes:
```bash
gitaiflow --telemetry history
```
Example:
```text
Consent history for ~/.gitaiflow_telemetry_consent (newest first, 2 records):
yes v1.0.6 2026-08-19T14:32:07+05:30
no v1.0.5 2026-08-18T10:11:03+05:30
```
The history is stored locally and is not part of the telemetry payload.
---
# Session-Only Control
You can override the saved consent for a single process by setting:
```bash
GITAIFLOW_TELEMETRY=true
```
or:
```bash
GITAIFLOW_TELEMETRY=false
```
The environment variable takes precedence over the saved consent.
### Enable for one command
```bash
GITAIFLOW_TELEMETRY=true gitaiflow --path .
```
### Disable for one command
```bash
GITAIFLOW_TELEMETRY=false gitaiflow --path .
```
This does **not** change the saved consent decision.
For example, if telemetry is permanently disabled:
```bash
gitaiflow --telemetry disable
GITAIFLOW_TELEMETRY=true gitaiflow --path .
```
that particular run can still send telemetry, but the saved state remains disabled.
Likewise, if telemetry is permanently enabled:
```bash
gitaiflow --telemetry enable
GITAIFLOW_TELEMETRY=false gitaiflow --path .
```
that run will not send telemetry, while future runs remain enabled.
---
# What Is Sent
When telemetry is enabled, each normal summary run produces a fixed telemetry payload.
The payload contains:
| Field | Description | Example |
|---|---|---|
| `install_id` | Random identifier generated locally for the gitaiflow installation | `550e8400-e29b-41d4-a716-446655440000` |
| `event` | Event type | `run` |
| `timestamp` | Run timestamp | `2026-08-19T14:32:07Z` |
| `gitaiflow_version` | Installed gitaiflow version | `1.0.6` |
| `ai_provider` | Configured AI provider | `gemini` |
| `model_name` | Configured model | `gemini-flash-lite-latest` |
| `target_type` | Type of target being summarized | `file` or `directory` |
| `files_changed_count` | Number of changed files detected | `4` |
| `tokens_estimated_in` | Estimated input tokens | `1832` |
| `tokens_estimated_out` | Estimated output tokens | `210` |
| `duration_ms` | Duration of the run in milliseconds | `2140` |
| `success` | Whether the gitaiflow run succeeded | `true` |
| `os` | Operating-system name | `linux` |
The payload is deliberately limited to these operational fields.
## What Is Never Sent
Telemetry does **not** send:
- repository name
- repository path
- repository URL
- file paths
- file names
- source-code contents
- diff contents
- Git author name
- Git author email
- Git branch
- Git base reference
- commit messages
- generated commit title
- generated commit body
- generated summary text
- contents of your `change-summary` artifacts
- API keys
- provider credentials
- `.env` contents
This separation is intentional: the information needed to understand gitaiflow usage is collected without sending the information needed to understand the contents of your repository.
---
# The `install_id`
`install_id` is a randomly generated UUID stored locally.
It is created when gitaiflow first needs one for telemetry and is reused for subsequent telemetry events from that local installation.
It exists so telemetry events can be associated with the same installation over time without using:
- your repository name
- your Git identity
- your email address
- your machine hostname
- your repository path
The install ID itself does not contain repository or user information.
It is stored locally at:
```text
~/.gitaiflow/install_id
```
## Removing the install ID
If you remove the local install ID:
```bash
rm ~/.gitaiflow/install_id
```
gitaiflow will generate a new random ID when telemetry next needs one.
This does not change telemetry consent.
---
# Local Usage Logging vs Remote Telemetry
These are two different mechanisms.
## Local usage log
gitaiflow always maintains a local usage log:
```text
~/.gitaiflow/usage.jsonl
```
It is used for local usage accounting and optional daily guardrails.
The local record can contain operational information such as:
- timestamp
- repository name
- target type
- provider
- model
- estimated token counts
- duration
- success/failure
- changed-file count
**This file stays on your machine.**
## Remote telemetry
Remote telemetry is separate and requires telemetry to be enabled.
Only the restricted telemetry payload described above is sent remotely.
Therefore:
```text
Local usage log
│
├── repository information may exist
├── local operational details
└── never transmitted automatically
Remote telemetry
│
├── anonymous operational fields
├── no repository identity
├── no file paths
└── no source/diff content
```
---
# Where Telemetry Is Sent
The default telemetry endpoint is:
```text
https://app.djangoplay.org/gitaiflow-telemetry/v1/events
```
The endpoint can be overridden with:
```bash
GITAIFLOW_TELEMETRY_URL=
```
For example:
```bash
GITAIFLOW_TELEMETRY_URL=https://telemetry.example.com/events \
GITAIFLOW_TELEMETRY=true \
gitaiflow --path .
```
This can be useful for organizations that operate their own compatible telemetry receiver.
> Only use a telemetry endpoint you trust. The endpoint receives the telemetry payload described in this document.
---
# Network Behavior
Telemetry uses an HTTP request with a short timeout.
The configured timeout is **3 seconds**.
Telemetry is deliberately non-critical to the main gitaiflow operation:
- network failures do not fail the gitaiflow run
- telemetry request errors are ignored
- an unavailable telemetry receiver should not prevent summary generation
- telemetry should not materially delay normal CLI operation
Conceptually:
```text
gitaiflow run
│
├── summary succeeds ───────────────→ successful CLI result
│
└── telemetry attempt
│
├── succeeds ───────────────→ continue normally
│
└── fails / times out ───────→ continue normally
```
---
# Interactive Consent
When telemetry has never been configured and gitaiflow is run interactively, it asks for consent.
The prompt is explicit:
```text
[TELEMETRY] Enable anonymous usage telemetry? [y/N]:
```
The default answer is **No**.
If you simply press Enter, telemetry remains disabled.
The consent notice explains both what can be sent and what is excluded.
Once you make a decision, that decision is stored locally and reused for subsequent runs.
## Upgrading gitaiflow
A previously stored consent decision is carried forward when gitaiflow is upgraded.
You are not expected to repeatedly answer the same consent question after every package upgrade.
You can change the decision at any time:
```bash
gitaiflow --telemetry enable
```
or:
```bash
gitaiflow --telemetry disable
```
The consent history records the change.
---
# CI and Non-Interactive Usage
Telemetry does not prompt for consent in non-interactive environments.
This is important for:
- GitHub Actions
- GitLab CI
- Jenkins
- shell scripts
- redirected commands
- piped commands
- automated build environments
If no saved consent exists and the process is non-interactive, telemetry defaults to **off**.
If you explicitly want telemetry in automation, set:
```bash
GITAIFLOW_TELEMETRY=true
```
For example:
```bash
GITAIFLOW_TELEMETRY=true gitaiflow --path .
```
If you do not want telemetry in automation, explicitly set:
```bash
GITAIFLOW_TELEMETRY=false
```
This is particularly useful when you want the behavior of a CI job to be unambiguous regardless of any consent state that may exist on the runner.
---
# Privacy Considerations
Telemetry does not replace the privacy boundary of your configured AI provider.
There are two separate external-data decisions in a normal gitaiflow workflow.
### AI provider
The filtered diff and prompt are sent to the AI endpoint required to generate the summary.
If you use a cloud provider, that provider receives the data necessary to perform the AI request.
If you use a local provider such as Ollama, the AI request can remain on your machine.
### gitaiflow telemetry
Telemetry is independent of the AI request.
When enabled, it sends only the fixed operational payload documented in this guide.
```text
gitaiflow
│
┌─────────────┴─────────────┐
│ │
▼ ▼
AI summary request Telemetry
│ │
▼ ▼
Configured AI provider Telemetry endpoint
│ │
│ └── Operational metadata only
│
└── Filtered diff + prompt
```
Therefore, disabling telemetry does **not** prevent data from being sent to a cloud AI provider if you use one. It only disables gitaiflow's separate anonymous usage reporting.
---
# Telemetry and AI Provider Costs
Telemetry itself is not an AI request and does not consume tokens from your configured AI provider.
Your AI provider may charge for the normal gitaiflow prompt/diff request according to that provider's pricing.
gitaiflow's local usage log provides estimated token counts and optional daily guardrails:
```bash
export GITAIFLOW_MAX_RUNS_PER_DAY=20
export GITAIFLOW_MAX_TOKENS_PER_DAY=50000
```
These limits are local courtesy warnings. They are not server-side quotas and cannot enforce provider billing limits.
Telemetry does not control these limits.
---
# Changelog Mode
`--changelog` is separate from the normal AI summary workflow.
For example:
```bash
gitaiflow --changelog --since 2026/08/01 --path .
```
Changelog generation uses existing change-summary JSON artifacts when available and can fall back to Git history.
It does **not** call an AI provider.
It also does **not** record a normal AI usage event or send normal run telemetry.
Telemetry described in this document applies to normal summary runs.
---
# Troubleshooting
## I was not asked about telemetry
This can be expected.
Check:
```bash
gitaiflow --telemetry status
```
If you are running in CI, a pipe, or a redirected command, gitaiflow intentionally does not prompt.
Use an explicit environment variable instead:
```bash
GITAIFLOW_TELEMETRY=true
```
or:
```bash
GITAIFLOW_TELEMETRY=false
```
## Telemetry is enabled but I do not see a network request
First check:
```bash
gitaiflow --telemetry status
```
Then verify that:
```bash
echo "$GITAIFLOW_TELEMETRY"
```
is not overriding the saved decision.
Remember that telemetry is sent only by normal summary runs. `--changelog` does not send normal run telemetry.
## I want to disable telemetry immediately
Run:
```bash
gitaiflow --telemetry disable
```
For only the current process:
```bash
GITAIFLOW_TELEMETRY=false gitaiflow --path .
```
## I accidentally enabled telemetry
You can disable it immediately:
```bash
gitaiflow --telemetry disable
```
The local consent history will retain the fact that telemetry was previously enabled.
## I deleted `~/.gitaiflow`
The telemetry consent decision is intentionally stored separately:
```text
~/.gitaiflow_telemetry_consent
```
Therefore, deleting `~/.gitaiflow` does not automatically reset telemetry consent.
The local usage log and install ID may be removed, but the saved telemetry decision remains.
---
# Files Used by Telemetry
| Path | Purpose | Remote? |
|---|---|---|
| `~/.gitaiflow/usage.jsonl` | Local usage records | No |
| `~/.gitaiflow/install_id` | Random local installation identifier | Its value may be included in telemetry when enabled |
| `~/.gitaiflow_telemetry_consent` | Persistent telemetry consent/history | No |
These files are local to the machine running gitaiflow.
---
# Quick Reference
### Check status
```bash
gitaiflow --telemetry status
```
### Enable permanently
```bash
gitaiflow --telemetry enable
```
### Disable permanently
```bash
gitaiflow --telemetry disable
```
### View consent history
```bash
gitaiflow --telemetry history
```
### Enable for one command
```bash
GITAIFLOW_TELEMETRY=true gitaiflow --path .
```
### Disable for one command
```bash
GITAIFLOW_TELEMETRY=false gitaiflow --path .
```
### Use a custom telemetry endpoint
```bash
GITAIFLOW_TELEMETRY_URL=https://example.com/events \
GITAIFLOW_TELEMETRY=true \
gitaiflow --path .
```
---
# Summary
gitaiflow telemetry is designed to be:
- **Opt-in**
- **Off by default**
- **Anonymous**
- **Limited to documented operational fields**
- **Independent from AI-provider requests**
- **Non-blocking**
- **Locally controllable**
- **Transparent about what is and is not transmitted**
Most importantly:
> **gitaiflow does not send your repository, file paths, source code, diffs, Git identity, commit messages, or generated summaries as telemetry.**